首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从另一个具有长进程的JFrame构建JFrame

从另一个具有长进程的JFrame构建JFrame
EN

Stack Overflow用户
提问于 2016-11-25 18:45:29
回答 2查看 204关注 0票数 1

我对JAVA非常陌生,我有一个问题(希望我的英语不是很糟糕)。

以下是我的过程:

  • 主要打开第一个JFrame,使用一个JButton (打开第二个JFrame)。
  • 在单击时,使用ActionLister,我调用进程打开第二个窗口,其中有一个黑色的背景(这非常好)。

但是,如果我在setVisible()我的第二个JFrame之后添加一个长进程(在代码中,只是一个睡眠(5000)),这个进程将以白色出现,等待睡眠(5000)结束后才变成黑色。

问题:

  • 有人能告诉我为什么第二个JFrames在进程结束前出现白色吗?也许我在构建JFrame时做错了什么?
  • 有人能告诉我如何在进程结束前显示我的第二个JFrame黑吗?

我搜索了很长一段时间,发现如果我的第二个窗口是直接建在主线程中,那么即使在进程结束前睡觉也是可以的。

但是当我在另一个线程中时(就像我点击按钮时),这是不好的!

第二部分:

点击第一个窗口中的按钮:第二个窗口出现(空有黑色背景)。然后,启动结果的计算。计算结果不会花20秒,每5秒就会找到一个元素。每次找到一个元素时,我都希望它显示在第二个窗口中。

为此,我从JFrame中添加了一个关于这个结果的观察者,每次找到一个元素时,它都会添加一个元素。我希望你能理解。这里是我想要做的事情的图片:

流程

这里我的项目.JAR:http://dl.free.fr/b5IUSStBJ

这是我的计算结果:

代码语言:javascript
复制
public void launchCalculateResult(){
    String[] tabelements = {"test1","test2", "test3", "test4", "test5"};
    for (int i=0; i < 5; i++){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        _elementslist.add(tabelements[i]);
        notifyObservers();
    }
}

您可以看到它每2秒在列表中添加一个元素,然后通知观察者(我的第二个窗口),然后观察者添加一个元素:

代码语言:javascript
复制
public void refresh(Observable o) {
    _otherwindow.addResultElement(_result.getLastElement());
}
  • 我的行为:

结果计算良好,最后,第二个窗口看起来很好,有它的5个元素。但是在搜索结果的过程中,我的第二个窗口仍然是空的和白的。。。

  • 我重复这个目标:每次在结果中添加一个元素时,我想在我的第二个窗口中显示它。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-25 18:48:47

您正在调用Swing事件线程上的长进程,这将限制线程执行其重要任务,包括绘制新的JFrame。

规范的解决方案是为您的长进程使用后台线程,对于Swing GUI,您可能希望使用SwingWorker --如果后台进程需要与GUI通信(通常是这样的)。

有关此问题和解决方案的详细信息,请参阅:在Swing中并发

附带问题:您通常不希望在应用程序中显示多个JFrames。关于为什么这很重要,以及如何改进这个设计,请查看多重JFrames

例如

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class SwingExample extends JPanel {
    private JButton openDialogBtn = new JButton(new OpenDialogAction("Open Dialog"));
    private JDialog dialog;
    private DialogPanel dialogPanel = new DialogPanel();

    public SwingExample() {
        setPreferredSize(new Dimension(400, 400));
        add(openDialogBtn);
    }

    private class OpenDialogAction extends AbstractAction {
        public OpenDialogAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            dialogPanel.setText("");
            if (dialog == null) {
                Window win = SwingUtilities.getWindowAncestor(SwingExample.this);
                dialog = new JDialog(win, "Dialog", ModalityType.MODELESS);
                dialog.add(dialogPanel);
                dialog.pack();
                dialog.setLocationRelativeTo(win);
            }
            new SwingWorker<Void, Integer> () {
                private final int maxI = 5;

                @Override
                protected Void doInBackground() throws Exception {
                    for (int i = 0; i < maxI; i++) {
                        publish(i);
                        Thread.sleep(1000);
                    }
                    return null;
                }

                protected void process(java.util.List<Integer> chunks) {
                    for (Integer chunk : chunks) {
                        dialogPanel.setText("Time: " + chunk);
                    }
                };

                protected void done() {
                    dialogPanel.setText("Done!");
                };
            }.execute();
            dialog.setVisible(true);
        }
    }

    private class DialogPanel extends JPanel {
        private JTextField textField = new JTextField(10);

        public DialogPanel() {
            setBackground(Color.BLACK);
            setPreferredSize(new Dimension(200, 200));
            add(textField);
        }

        public void setText(String text) {
            textField.setText(text);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        SwingExample mainPanel = new SwingExample();
        JFrame frame = new JFrame("SwingExample");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}

示例2:使用JList<String>传递给SwingWorker<Void, String>的句柄字符串

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class SwingExample extends JPanel {
    private JButton openDialogBtn = new JButton(new OpenDialogAction("Open Dialog"));
    private JDialog dialog;
    private DialogPanel dialogPanel = new DialogPanel();

    public SwingExample() {
        setPreferredSize(new Dimension(400, 400));
        add(openDialogBtn);
    }

    private class OpenDialogAction extends AbstractAction {
        public OpenDialogAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            dialogPanel.clearList();
            if (dialog == null) {
                Window win = SwingUtilities.getWindowAncestor(SwingExample.this);
                dialog = new JDialog(win, "Dialog", ModalityType.MODELESS);
                dialog.add(dialogPanel);
                dialog.pack();
                dialog.setLocationRelativeTo(win);
            }
            new SwingWorker<Void, String>() {
                @Override
                protected Void doInBackground() throws Exception {
                    String[] tabelements = { "test1", "test2", "test3", "test4", "test5" };
                    for (int i = 0; i < 5; i++) {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        publish(tabelements[i]);
                    }
                    return null;
                }

                protected void process(java.util.List<String> chunks) {
                    for (String chunk : chunks) {
                        dialogPanel.addText(chunk);
                    }
                };

                protected void done() {
                    dialogPanel.addText("Done!");
                };
            }.execute();
            dialog.setVisible(true);
        }
    }

    private class DialogPanel extends JPanel {
        private DefaultListModel<String> listModel = new DefaultListModel<>();
        private JList<String> jList = new JList<>(listModel);

        public DialogPanel() {
            jList.setPrototypeCellValue("ABCDEFG HIJKLMNOP");
            jList.setVisibleRowCount(6);
            JScrollPane scrollPane = new JScrollPane(jList);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

            setBackground(Color.BLACK);
            setPreferredSize(new Dimension(200, 200));
            add(scrollPane);
        }

        public void clearList() {
            listModel.clear();
        }

        public void addText(String text) {
            listModel.addElement(text);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        SwingExample mainPanel = new SwingExample();
        JFrame frame = new JFrame("SwingExample");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}
票数 2
EN

Stack Overflow用户

发布于 2019-03-01 08:48:02

代码语言:javascript
复制
//Make constructor class for both JFrame then 
 //write this code into your JFrame where your button is accesing another JFrame
 //Note:- jb=button var name,
 //       jf=JFrame vatr name,
 //       addnew()=JFrame Class to be open.

  jb.addActionListener(new ActionListener() { 
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub
        new addnew();
        jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       } 
   });

也许也能用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40810857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档