移动后,组件不再可调整大小

时间:2010-06-15 16:22:52

标签: java swing resize visible

我的问题与摇摆编程有关。我想通过从其父面板(组件a)中删除它并将其添加到组件a的父组件(组件b)之一来扩大组件(组件x)。在此之前,我在b中的所有组件上调用setVisible(false)。之后我想通过将其从b中删除并添加。

来实现

之后,所有组件都不再可调整大小。

为什么?

一个简单的例子:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;

public class SwingTest {

    private static ViewPanel layer1;
    private static JFrame frame;
    private static JTabbedPane tabbedPane;
    private static ViewPanel root;

    public static void main(String[] args) {
        frame = new JFrame();
        frame.setLayout(new BorderLayout());
        frame.setMinimumSize(new Dimension(800, 600));

        root = new ViewPanel();
        root.setBackground(Color.blue);
        root.setPreferredSize(new Dimension(400, 600));
        root.setLayout(new BorderLayout());
        root.add(new JLabel("blue area"));

        layer1 = new ViewPanel();
        layer1.setBackground(Color.red);
        layer1.setPreferredSize(new Dimension(400, 600));
        layer1.setLayout(new BorderLayout());

        tabbedPane = new JTabbedPane();
        tabbedPane.add("A", new JLabel("A label"));
        tabbedPane.setPreferredSize(new Dimension(400, 600));

        layer1.add(tabbedPane);

        root.add(layer1);
        frame.add(root, BorderLayout.NORTH);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        Thread t = new Thread() {

            @Override
            public void run() {
                try {
                    Thread.sleep(8000);
                    System.out.println("start");
                    for (Component c : root.getComponents()) {
                        c.setVisible(false);
                    }
                    layer1.remove(tabbedPane);
                    root.add(tabbedPane);

                    Thread.sleep(8000);

                    root.remove(tabbedPane);
                    layer1.add(tabbedPane);

                    for (Component c : root.getComponents()) {
                        c.setVisible(true);
                        c.repaint();
                    }
                } catch (InterruptedException e) {
                    //...
                }
            }
        };
        t.start();
    }
}

1 个答案:

答案 0 :(得分:1)

  

之后,所有组件都不再可调整大小。

我认为LayoutManager的选择掩盖了效果。一般来说,在event dispatch thread上构建GUI是个好主意,使用sleep()阻止该线程是个坏主意。此替代示例使用javax.swing.Timer在计时器的actionPerformed()方法中定期更改内容。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;

public class SwingTest implements ActionListener, Runnable {

    private JFrame frame;
    private ViewPanel root;
    private ViewPanel layer1;
    private JTabbedPane tabbedPane;
    private Timer t = new Timer(1000, this);
    private boolean remove = true;

    public static void main(String[] args) {
        EventQueue.invokeLater(new SwingTest());
    }

    private static class ViewPanel extends JPanel {

        public ViewPanel(Color color) { // default FlowLayout
            this.setPreferredSize(new Dimension(400, 500));
            this.setBackground(color);
        }
    }

    @Override
    public void run() {
        frame = new JFrame(); // default BorderLayout
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(600, 600));
        root = new ViewPanel(Color.blue);
        root.add(new JLabel("Blue area"));
        layer1 = new ViewPanel(Color.red);
        tabbedPane = new JTabbedPane();
        tabbedPane.add("A", new JLabel("A label", JLabel.CENTER));
        tabbedPane.setPreferredSize(root.getPreferredSize());
        layer1.add(tabbedPane);
        root.add(layer1);
        root.add(new JLabel("Blue area"));
        frame.add(root, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        t.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (remove) {
            for (Component c : root.getComponents()) {
                c.setVisible(false);
            }
            layer1.remove(tabbedPane);
        } else {
            layer1.add(tabbedPane);
            for (Component c : root.getComponents()) {
                c.setVisible(true);
            }
        }
        remove = !remove;
    }
}