用GridBagLayout在Frame上绘制Grahpics2D对象

时间:2014-06-19 12:43:22

标签: java swing layout-manager graphics2d gridbaglayout

我正在尝试绘制一个彩色条,随着时间的推移它会变大。它在我使用默认布局管理器时有效,但是当我试图用GridBagLayout实现它时,它不会。我编写了一个测试项目,仅用于测试目的,以调查问题所在。我添加了几个按钮,只是为了除了graphics2D对象之外还有别的东西,所以它看起来像我正在工作的实际项目。但过了几天,我不得不承认我没有线索,出了什么问题。我希望有人可以帮助我!

提前,不要对代码中使用的一些词语感到困惑。我的母语不是英语。

import java.awt.*;
import javax.swing.*;
import java.util.TimerTask;
import java.util.Timer;


public class FarbBalkenTest extends JPanel {

static Timer timer = new Timer ();
static TimerTask task ;
static int time;

public static void main(String[] args) {

    FarbBalkenTest fbt = new FarbBalkenTest();
    fbt.init();


}

public static void addComponent(Container cont, GridBagLayout gbl, Component c, int x, int y, int width, int height, double weightx, double weighty ){

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridx=x;
    gbc.gridy=y;
    gbc.gridwidth=width;gbc.gridheight=height;
    gbc.weightx=weightx;gbc.weighty=weighty;
    gbl.setConstraints(c,gbc);
    cont.add(c);

}


public void init (){

    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setBackground(new Color(230,230,230));
    Container c = frame.getContentPane();
    GridBagLayout gbl = new GridBagLayout();
    c.setLayout(gbl);
    ZeichenTest z_test = new ZeichenTest();

    addComponent(c,gbl, new Button("top left"), 0,0,1,1,1.0,1.0);
    addComponent(c,gbl, new Button("top right"), 2,0, 1,1,1.0,1.0);
    addComponent(c, gbl,z_test, 1,1,1,1,1.0,1.0);
    addComponent(c,gbl, new Button("down left"),0,2,1,1,1.0,1.0);
    addComponent(c,gbl, new Button("down right"),2,2,1,1,1.0,1.0);
    frame.setSize(500,500);
    frame.setVisible(true);


    task = new TimerTask(){
        public void run(){
            frame.repaint();
            time+= 20;
            System.out.println(time);
        }
    };
    timer.scheduleAtFixedRate(task, 0, 1000);



}
public class ZeichenTest extends JComponent  {

    public void paintComponent (Graphics g){

            Graphics2D g2d = (Graphics2D) g;

            Color startgreen = new Color(50,205,50);

            Color endred = new Color (255, 97, 3);

            GradientPaint startend = new GradientPaint(0,25 , startgreen, 400, 25 , endred );

            g2d.setPaint (startend);

            g2d.fillRect(50, 200 , time, 50);
        }


    }

}

1 个答案:

答案 0 :(得分:5)

  

“当我使用默认的布局管理器时它会起作用,但是当我试图用GridBagLayout实现它时,它不会。”

GBL尊重首选尺寸。您的ZeichenTest没有。您需要通过覆盖getPreferredSize()来明确设置它。 (JFrame的默认布局,即BorderLayout不尊重首选尺寸,并会拉伸面板以适应)

public class ZeichenTest extends JComponent {
    ...
    @Override
    public Dimension getPreferredSize() {
        return new Dimension( ... , ... );
    }
}

另请注意,在设置组件的首选大小后,只需在框架上调用pack(),而不是setSize()pack()将根据首选尺寸“适合”所有内容。实际上,您可以通过调用pack()而不是setSize()来测试您的组件当前没有首选大小,并且您会看到启动时框架缩小。但是,如果您覆盖组件的getPreferredSize()并调用包,则框架的大小将根据新的首选大小。


其他重要说明:

  • 使用java.swing.Timer代替TimerTask。重绘应该在EDT上完成,Swing Timer会为你处理。详情请见How to Use Swing Timer

  • 我认为你的意思是repaint() ZeichenTest的实例和的框架。它有所作为。

  • 始终在super.paintComponent方法中调用paintComponent,以免留下令人讨厌的油漆

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
    }
    
  • 应始终在事件调度线程(EDT)上运行Swing应用程序。见Initial Threads。基本上,在这种情况下,只需将main代码包装在SwingUtilities.invokeLater(...)

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                FarbBalkenTest fbt = new FarbBalkenTest();
                fbt.init();
            }
        });
    }