2015-04-24 3 views
2

Я хочу нарисовать несколько разных JComponents в одном JPanel. Я создаю некоторые JComponents с различными методами рисования. Затем создайте объекты в главном и поместите их в JFrame. Моя проблема заключается в том, что в окне отображается только последний объект.добавить различные jcomponents в jframe в java

Как я могу разместить разные JComponents в окне, не удаляя или не перекрашивая старые?

(Model2 работает как Model1, но paintComponent немного отличается)

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class GuiModel{ 
    public static void main(String[] args){   
     JFrame frame = new JFrame();   
     frame.setSize(600, 600); 
     frame.setLocation(150, 150); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true);     

     frame.getContentPane().add(new Model1(0,0)); 
     frame.getContentPane().add(new Model2(25,37,true));    

    } 
} 
import java.awt.Color; 
import java.awt.Graphics; 
import javax.swing.JComponent;  
public class Model1 extends JComponent { 
    private int xPos, yPos; 


    Model1 (int x, int y){ 
     this.xPos = x; 
     this.yPos = y; 
    } 

    @Override 
    protected void paintComponent(Graphics g) {  
     g.setColor(Color.BLACK); 
     g.drawOval(xPos, yPos, 5, 5);     
    } 
} 

ответ

3

При выполнении пользовательской картины:

  1. Вы должны переопределить getPreferredSize() метод компонента, чтобы вернуть размер компонента поэтому менеджер компоновки может отобразить компонент. Прямо сейчас размер ваших компонентов равен (0, 0), поэтому рисовать нечего.

  2. Покраска компонента выполняется из (0, 0), а не (x, y). Затем, если вы поместите компонент в определенную точку на панели, вы используете setLocation (x, y), чтобы сообщить Swing, где рисовать компонент.

  3. Если вы хотите покрасить компонент в случайном положении, вам также необходимо использовать нулевой макет на панели, и вы также должны установить размер компонента. Чтобы установить размер компонента, вы должны использовать setSize (getPreferredSize()) в своем конструкторе.

Так ваш класс Model1 будет выглядеть примерно так:

public class Model1 extends JComponent { 
    //private int xPos, yPos; 

    Model1 (int x, int y){ 
     //this.xPos = x; 
     //this.yPos = y; 
     setLocation(x, y); 
     setSize(getPreferredSize()); 
    } 

    @Override 
    public Dimension getPreferredSize() 
    { 
     return new Dimension(5, 5); 
    } 
    @Override 
    protected void paintComponent(Graphics g) {  
     g.setColor(Color.BLACK); 
     //g.drawOval(xPos, yPos, 5, 5);     
     g.drawOval(0, 0, 5, 5);     
    } 
} 
+0

спасибо! теперь это работает! –

2

JFrame использует BorderLayout по умолчанию. При добавлении компонентов без указания ограничений каждый компонент будет помещен в CENTER.

Либо укажите ограничения, либо если для вас недостаточно BorderLayout, переключитесь на другой макет.

Чтобы добавить ограничения:

frame.add(new Model1(0,0), BorderLayout.NORTH); 

Я предлагаю читать How to use BorderLayout, а также guides on the other predefined layouts. Кроме того, не стесняйтесь смотреть онлайн для сторонних макетов, если ни один из макетов, доступных через JDK, не соответствует вашим потребностям. Или вы можете создать свой собственный LayoutManager, если нет раскладки не существует, что соответствует вашим потребностям


Я также рекомендую использовать pack() для размера рамку на основе компонентов внутри вместо того, чтобы его размер с frame.setSize. Это гарантирует, что ваша рама плотно обертывается вокруг чего-либо внутри, не оставляя пустых мест. Если вы хотите пустые пространства, это должно обрабатываться менеджером компоновки

-1

Вы можете указать размер компонентов или использовать макеты для размещения объектов не в одном месте. Или вы можете создать копию графики и писать в нем:

protected void paintComponent(Graphics g) { 
    g = g.create(); 
    g.setColor(Color.BLACK); 
    g.drawOval(xPos, yPos, 5, 5); 
    g.dispose(); 
} 

Но последний вариант не эффективен: он делает копию графики на каждой перерисовке.