我想知道如何编写以下代码,或者只是一个方法:
public void run (){
public void paint(Graphics g) {
g.fillRect(20, 20, 20, 20);
for (int i = 20; i < 1000; i++) {
g.fillRect(20, i, 20, 20);
Thread.sleep(10);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我发现我无法创建此代码的线程,因为我得到了一个非法的表达式错误启动,这是公平的,但我没有看到解决方法.
我有一个 JFrame,它根据您单击的 MenuItem 显示 JPanel。它可以工作,但是现在我需要在将 JPanel 添加到框架并显示它后调用一个方法(因为我在该面板内使用 JFreeChart 并且我必须chartPanel.repaint()在 JPanel 可见时调用):
this.getContentPane().add( myjpanel, BorderLayout.CENTER ); //this = JFrame
this.validate();
myjpanel.methodCalledOnceDisplayed();
Run Code Online (Sandbox Code Playgroud)
看起来没问题吗?真的myjpanel被展示了吗?好像不是:
public void methodCalledOnceDisplayed() {
chartPanel.repaint()
}
Run Code Online (Sandbox Code Playgroud)
这不起作用(chartPanel.getChartRenderingInfo().getPlotInfo().getSubplotInfo(0)正在抛出 IndexOutOfBoundsException)。这意味着调用重绘时 JPanel 不可见,我测试了以下内容:
public void methodCalledOnceDisplayed() {
JOptionPane.showMessageDialog(null,"You should see myjpanel now");
chartPanel.repaint()
}
Run Code Online (Sandbox Code Playgroud)
现在它起作用了,我myjpanel在警报后面看到了,正如预期的那样,重新绘制了 chartPanel 并且没有发生异常。
编辑:SSCCE(需要 jfreechart 和 jcommon:http ://www.jfree.org/jfreechart/download.html )
导入 java.awt.BorderLayout; 导入 java.awt.EventQueue; 导入 java.awt.Font; 导入 javax.swing.JButton; 导入 javax.swing.JFrame; 导入 javax.swing.JLabel; 导入 javax.swing.JOptionPane; 导入 javax.swing.JPanel; 导入 javax.swing.border.EmptyBorder; 导入 …
在这种情况下,上下文是创建一个与模型集成的游戏循环,并每帧更新一次视图。听众与控制器接口,控制器更新模型,repaint()处理来自模型视图更新(上覆盖paintComponent()上一JPanel)。
合适的答案包括“从不”,哈哈。
这个问题我认为有一个更好的答案,所以它不应该违反规则。
我问这个是因为主游戏循环是一个Runnable我锁定到 60FPS的实例(目前大致上。几毫秒的差异,因为当前的渲染循环非常便宜,并且 1000 / 60 每个循环损失一两毫秒)。不通过锁定帧速率Thread.sleep()会导致每秒23亿帧(显然),这可以理解地使我的 CPU 崩溃。不是问题说起来,更多的是为什么需要帧锁定的例子。
然而,在我遇到的每一个答案、每一条评论中,他们中的大多数人都说“为什么你甚至Thread.sleep()不想让 EDT 睡觉”。如果您的循环中存在导致无响应的缺陷,这是可以理解的,但在我尚未组装的应用程序中,情况并非如此。我已经阅读了所有相关的事件调度线程文档,如何使用 Swing 计时器等。我什至自己也使用过计时器,还有 SwingWorkers(在一种情况下,将图标加载委托给后台以防止 GUI 实例化时出现阻塞) .
这里甚至有首选方法吗?我还没有遇到过很多/任何不依赖于 libgdx 的 Java 独立游戏解决方案。
我有一个关于'事件派遣线程'的问题.我有一个Main类,也是一个JFrame.它初始化代码中的其余组件,其中一些不涉及Swing,其中一些涉及.使用EDT简单地初始化Main类就足够了吗?...
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Main();
}
});
}
Run Code Online (Sandbox Code Playgroud)
这样一切都将在Event Dispatcher线程上运行.
我正在开发一个包含大约十个不同数据源的applet(例如statistics/error-log/...).每个数据源由单个网络连接更新,并通过观察器机制报告更新.applet具有不同的视图,可以显示部分数据.每个视图只对数据的某些部分感兴趣,并在必要的Observables中将其自身注册为Observer.
视图(扩展的JPanels)主要由标准的摆动组件组成(例如JLabel,JButton,......).视图中组件的某些属性取决于基础数据模型中的信息.
例:
StatisticPanel::paintComponent(Graphics g) {
clearStatisticButton.setEnabled(stat.hasEntries());
minValueLabel.setText(stat.getMinValue());
super.paintComponent(g);
}
Run Code Online (Sandbox Code Playgroud)
这个逻辑paintComponent()在StatisticPanel 的方法中实现,update()方法只调用repaint(),因为我不想操纵EDT之外的组件.
这是在多线程环境中更新swing组件的预期方法吗?使用Runnable更好SwingUtitlies.invokeLater()吗?这个问题有更好的方法吗?
我还有空白问题JOptionPane.基于SO和Java Docs的研究,这显然与不使用它有关EDT.我的问题是EDT它及其方法究竟是如何适用的JOptionPane?例如,终端错误输出清楚地表明JOptionPane下面没有运行EDT.特别缺少什么,以及如何Runnable适应?
import javax.swing.*;
public class PaneDemo
{
public static void main(String[] args)
{
final String[] TEXT ={
//message
"Hello, World!",
//title
"Greeting"};//end TEXT
showMyPane(TEXT);
}//end main
public static void showMyPane(final String[] TEXT)
{
JOptionPane.showMessageDialog(null, TEXT[0], TEXT[1],
JOptionPane.INFORMATION_MESSAGE);
if(!SwingUtilities.isEventDispatchThread())
{
System.err.println("Err: GUI failed to use EDT.");
}//end if(!SwingUtilities.isEventDispatchThread())
}//end showMyPane
}//end class PaneDemo
Run Code Online (Sandbox Code Playgroud)
答案建议添加invokeLater.然而,这似乎并没有在BlueJ中表现得很好.

isEventDispatchThread()仍然在终端中返回错误.这只是因为它现在在错误的位置?
我对java很新,并开始使用不同的线程来使用wait()或sleep()在我的代码的一部分上运行其他代码.
对于这个项目,我使用JFrame与javax.swing.*和java.awt.*进口.我想要做的是让其中一个线程(在我的代码中它是主要的,起始线程)允许玩家在tic tac toe board上选择一个空间,当他们点击它时,它将改变图标,并且然后AI将等待1秒钟,然后从我创建的第二个线程回放.
不幸的是,每当我调用ait.sleep(1000)(ait是我的线程名称)时,两个线程都会在完成执行之前等待1秒.谁能告诉我为什么睡一个线程会阻止我的整个执行?
java swing multithreading event-dispatch-thread thread-sleep
我最近发现了一个示例代码:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
Run Code Online (Sandbox Code Playgroud)
该createAndShowGUI()方法打开用户界面窗口.然后我尝试修改代码如下:
public static void main(String[] args) {
createAndShowGUI();
}
Run Code Online (Sandbox Code Playgroud)
两个版本都同样有效.有什么不同?
我知道Swing单线程规则(来自Java Concurrency in Practice):
应仅从事件派发线程创建,修改和查询Swing组件和模型.
反过来也是如此吗?我维护一些事务日志代码,将事件信息写入文件,有时在EDT上执行此操作.这是一种不好的做法吗?
在运行Swing程序的过程中,是否首先生成了UI线程(事件派发线程,EDT)?据推测,任何给定的JVM都可以做任何想做的事情(例如,在启动时始终产生EDT,无论是否曾经使用过),但实际上EDT通常是在什么时候创建的?
首次调用SwingUtilities.invokeLater()时是否会创建它?首次实例化JPanel时?如果事件泵与创建EDT分开启动,那么这种情况何时会发生?
java ×10
swing ×10
applet ×1
awt ×1
concurrency ×1
invokelater ×1
jfreechart ×1
joptionpane ×1
paint ×1
thread-sleep ×1