Swing调整大小缓慢/跳跃

时间:2012-11-28 14:35:51

标签: java swing resize

我使用简单的渐变扩展JComponent并调整paintComponent()方法制作了自己的BottomBar。

然后我将它添加到使用BorderLayout的JFrame的SOUTH。

一开始看起来都很正确。 当我调整框架大小时,BottomBar会重新绘制并正确设置到新位置。想一想,它发生在几毫秒到晚,所以人们可以看到JFrame的背景一秒钟。

有趣的是,当我将执行环境设置为Java-SE 1.6时,它可以工作......(而不是1.7) 另外,我在Mac上运行它,如果这有所不同。

Screenshot comparing window when resized and when not


代码 - JButton示例

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;


public class Main {

    public static void main(String args[]){
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Resize Example");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JButton(), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}

代码 - BottomBar示例

主:

public class Main {
    public static void main(String args[]){
        Frame window = new Frame();
        window.setSize(500, 400);
        window.setVisible(true);
    }
}

框:

import java.awt.BorderLayout;

import javax.swing.JFrame;


public class Frame extends JFrame{
    private static final long serialVersionUID = 1L;

    public Frame() {
        setLayout( new BorderLayout() );
        getContentPane().add( BorderLayout.SOUTH, new BottomBar() );
    }
}

BottomBar

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JComponent;

public class BottomBar extends JComponent {
    private static final long serialVersionUID = 1L;

    public BottomBar() {
        setSize(200, 30);
        setPreferredSize( new Dimension(200, 30) );
    }

    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;

        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        GradientPaint gradient = new GradientPaint(0, 0, new Color(185, 185, 185), 0, getHeight() , new Color(151, 151, 151) );
        g2.setPaint(gradient);
        g2.fillRect(0, 0, getWidth(), getHeight());

        g2.setColor( new Color(64, 64, 64) );
        g2.drawLine(0, 0, getWidth(), 0);
        g2.setColor( new Color(215, 215, 215) );
        g2.drawLine(0, 1, getWidth(), 1);
    }
}

1 个答案:

答案 0 :(得分:3)

我无法重现你在1.6上描述的效果;您可以尝试1.7下面的sscce。请注意,您的示例有几个建议:

  • 如[{3}}所述,避免使用setXxxxSize()。如果您只想在SOUTH中使用30像素的高标准栏,请覆盖getPreferredSize(),如下所示。如果您以后决定添加组件,则需要添加布局管理器。

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(0, 30);
    }
    
  • 使用pack()Window采用所附组件的首选大小。我已向JPanel添加了任意大小CENTER;调整框架大小以查看栏在SOUTH中的水平增长方式。

  • 应在here构建和操作Swing GUI对象。

BottomBar

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/13610367/230513 */
public class Main {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("BottomBar");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JPanel() {

                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(320, 240);
                    }
                }, BorderLayout.CENTER);
                frame.add(new BottomBar(), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }

    private static class BottomBar extends JComponent {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(0, 30);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            GradientPaint gradient = new GradientPaint(
                0, 0, new Color(185, 185, 185),
                0, getHeight(), new Color(151, 151, 151));
            g2.setPaint(gradient);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(new Color(64, 64, 64));
            g2.drawLine(0, 0, getWidth(), 0);
            g2.setColor(new Color(215, 215, 215));
            g2.drawLine(0, 1, getWidth(), 1);
        }
    }
}