我对JAVA相当陌生,我有一个问题(我希望我的英语不是太差)。
以下是我的过程:
但是,如果我在setVisible()第二个JFrame之后添加一个长进程(在我的代码中,只有一个睡眠(5000)),那么这个进程将以白色显示,并在黑色之前等待睡眠(5000)结束。
问题:
但是当我在另一个线程中(比如当我点击按钮时),那就不好用了!
第二部分:
点击第一个窗口的按钮:显示第二个窗口(黑色背景的空窗口)。然后,启动结果的calcul。计算结果不需要20秒,每5秒会找到1个元素。每次找到一个元素,我都希望它显示在第二个窗口中。
流程
这里是我的project.jar:http://dl.free.fr/b5iusstbj
这里是我的计算结果:
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();
}
}
public void refresh(Observable o) {
_otherwindow.addResultElement(_result.getLastElement());
}
结果计算良好,最后第二个窗口看起来很好,有它的5个元素。但是在搜索结果的过程中,我的第二个窗口仍然是空的和白色的。..
您正在调用Swing事件线程上的长进程,这将使线程无法执行其重要的工作,包括绘制新的JFrame。
规范的解决方案是为长进程使用后台线程,而对于Swing GUI,您希望使用SwingWorker--如果后台进程需要与GUI通信(通常是这样)。
有关此问题和解决方案的详细信息,请查看:Swing中的并发
附带问题:您通常不希望在应用程序中显示多个JFrames。为了了解这一点的重要性以及如何改进这个设计,请查看多个JFrames
例如:
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:使用SwingWorker
处理传递到JList
中的字符串
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);
}
}
问题内容: 我下棋。我写了3节课。如果是游戏则为第一。(棋盘,棋子等),另外一个用于菜单。(新,打开,设置时间等按钮) 他们两个都使用JFrame。 我想将上述两个类都放在第3类中。例如,“游戏”窗口在左侧,菜单在右侧。第三类还将通过JFrame显示整个应用程序。 怎么做? 问题答案: 您不能将一个JFrame放入另一个。您在这里有几个设计选择。您可以将JFrames更改为JPanels。这可能是
问题内容: 如何从另一个类中处置JFrame?我的代码在下面列出。我使用Netbeans生成表单来生成窗口。我想使用另一个类进行处理(名称为needDispose)。 NETBEANS GENERATE (重要方法是getMainFrame()) 问题答案: 这是一个如何从另一个本身就是JFrame的类中释放JFrame的示例:
问题内容: 嗨,我试图将一些文本附加到同一包中另一个类的一个小问题。以下是与JFrame有关的主要类: 我包括测试变量只是为了轻松地重新创建问题,但是无论何时运行append函数,jFrame的文本区域中都不会出现任何内容。在我的方案中,我让客户端从服务器接收文本,然后将其附加到文本框中。 顺便说一句,我正在为JFrame使用IntelliJ GUI设计器。我只包含了重新创建问题所需的代码。我仍在
如何从另一个类中处理?下面列出了我的代码。 处置类别: <代码>主窗口。main\u f.dispose()不起作用,因为它不是变量。你能帮助我吗?
我有3个不同的JFrames。一个是一个登录页面,另一个有,第三个是主页。现在我想要的是,当我们登录时,我想在登录页面上方显示,并在完成进度到100%时,我想关闭两个框架并打开第三个,这是主页。请好心帮我完成这项工作。谢谢//这是代码部分。 }//这打开我的进度条的第二个JFrame //在Progressbar页面的下一页,我有这个代码 //现在我想要的是,在进度条完成后,我想处理登录页面和只打
问题内容: 众所周知,我是一名完全的Java新手。我已经尝试过对此进行研究(通过阅读StackOverflow上的其他文章,谷歌搜索,并问一个不太喜欢Java新手的朋友),但我不知道。答案可能是明确而容易的,但我对此视而不见。我正在尝试从其他框架中放置A。 我的应用程序应该按以下方式工作: 按下框架X时有一个按钮:产生框架Y 框架Y有一个按钮,当按下时:产生框架Z 按下框架Z时有一个按钮:在放置框