【问题标题】:Updating Swing UI inside button click event在按钮单击事件中更新 Swing UI
【发布时间】:2015-07-13 07:40:53
【问题描述】:

我有一个摇摆应用程序。我正在尝试显示加载玻璃窗格 从数据库中读取数据。但这种行为不是我所期望的。

public class Sample {
                    JFrame frame;
                    JPanel loadingPanel;
                    JLabel iconLabel;
                    JPanel glassPane;

                    private PropertyChangeSupport changeListeners = new PropertyChangeSupport(this);

                    public static void main(String[] args) {
                        EventQueue.invokeLater(new Runnable() {
                            public void run() {
                                try {
                                    Sample window = new Sample ();
                                    window.frame.setVisible(true);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }

                    public Sample () {
                        initialize();
                    }


                    private void initialize() {
                        frame = new JFrame();
                        frame.setBounds(100, 100, 450, 300);
                        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                        JPanel panel = new JPanel();
                        panel.setSize(new Dimension(500,500));
                        frame.getContentPane().add(panel);
                        panel.setLayout(null);

                        // ---------Select button--------------------------------
                        JButton btnSelect = new JButton("Select");
                        btnSelect.addActionListener(loadDataActionListner);
                        btnSelect.setBounds(132, 7, 137, 32);
                        btnSelect.setFocusPainted(false);
                        panel.add(btnSelect);


                        glassPane = new GlassPanel();
                        glassPane.setOpaque(false);
                        glassPane.setLayout(new GridBagLayout());
                        glassPane.add(new JLabel("loading... "));
                        frame.setGlassPane(glassPane);

                        ChangeListener listener = new ChangeListener(this);
                        changeListeners.addPropertyChangeListener(listener);
                    }

                    public void changeVisibility(boolean  visibility){
                       glassPane.setVisible(visibility);
                       frame.validate();
                       frame.repaint();
                    }


                    ActionListener loadDataActionListner = new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                          SwingUtilities.invokeLater(new Runnable() {
                          @Override
                          public void run() {
                            JFileChooser fileChooser = new JFileChooser();
                            fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
                            int result = fileChooser.showOpenDialog(frame);
                            if (result == JFileChooser.APPROVE_OPTION) {

                                changeListeners.firePropertyChange("visibility", false, true); //Line 01
                                Response response = DataManager.getInstance().loadData("myfile.txt");
                                changeListeners.firePropertyChange("visibility", true, false);

                            }
                           }
                          });

                        }
                    };
                }

        public class GlassPaneUpdateWorker extends SwingWorker<Object, Boolean> {

            private boolean visibility;
            private Sample sample;

            public GlassPaneUpdateWorker(Sample  sample) {
                this.sample = sample;
            }

            @Override
            protected Object doInBackground() throws Exception {
                publish(visibility);
                return null;
            }

            @Override
            protected void process(List<Boolean> chunks) {
                if (chunks != null && !chunks.isEmpty()) {
                    sample.changeVisibility(chunks.get(0));
                }
            }

            protected void changeVisibility(boolean visibility) {
                this.visibility = visibility;
            }

        }

        public class ChangeListener  implements PropertyChangeListener{

            private Sample sample;

            public ChangeListener(Sample sample) {
                this.sample =  sample;
            }

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                GlassPaneUpdateWorker glassPaneUpdater = new GlassPaneUpdateWorker(sample);
                glassPaneUpdater.changeVisibility((Boolean)evt.getNewValue());
                glassPaneUpdater.execute();
            }

        }

在 actionPerformed 方法中执行所有代码块后,会出现加载玻璃面板。我该如何更改这一点,以便在“第 01 行”执行后更新 UI。?

【问题讨论】:

  • 避免使用null 布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正
  • 对于exampleexampleexample
  • @MadProgrammer 我将代码更改为使用 SwingWorker。但我仍然得到相同的结果。我在这里错过了什么?
  • 您使用 SwingWorker 不正确。您想输入“响应响应 = DataManager.getInstance().loadData("myfile.txt");”在 doInBackground() 内部。这样,您就可以在与事件调度线程不同的线程中运行数据库操作。

标签: java swing


【解决方案1】:

我能够通过使用 SwingWorker 来完成这项工作,如下所示,无需任何侦听器。

ActionListener loadDataActionListner = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFileChooser fileChooser = new JFileChooser();
                    fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
                    int result = fileChooser.showOpenDialog(frame);
                    if (result == JFileChooser.APPROVE_OPTION) {
                        SwingWorker<?, ?> worker = new SwingWorker<Void, Integer>() {
                            protected Void doInBackground() {
                                showLoadingPanel();
                                Response response = DataManager.getInstance().loadData("myfile.txt");
                                hideLoadingPanel();
                                //Do something..
                                return null;
                            }
                        };
                        worker.execute();

                    }
                }
            });

        }
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    相关资源
    最近更新 更多