在这里作为答案给出的许多Swing片段中,有一个SwingUtilities#invokeLater来自该main方法的调用:
public class MyOneClassUiApp {
private constructUi() {
// Some Ui related Code
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MyOneClassUiApp().constructUi();
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
但根据Threads and Swing的文章,从主线程构造UI是安全的:
一些方法是线程安全的:在Swing API文档中,线程安全方法用以下文本标记:
虽然大多数Swing方法都不是,但这种方法是线程安全的.
应用程序的GUI通常可以构造并显示在主线程中:只要没有实现组件(Swing或其他),以下典型代码是安全的:
public class MyApplication {
public static void main(String[] args) {
JFrame f = new JFrame("Labels");
// Add components to
// the frame here...
f.pack();
f.show();
// Don't do any more GUI work here...
} …Run Code Online (Sandbox Code Playgroud) 我正在使用这里JScrollNavigator描述的组件,以便为我嵌入的大型"画布式"CAD组件提供导航窗口.JScrollPane
我已经尝试调整JScrollNavigator绘制画布的缩略图以向用户提供一些额外的上下文.但是,执行此操作会导致应用程序主框架的呈现损坏.具体来说,它是调用paint(Graphics)视口组件(即我的主画布)的动作,传入由此Graphics创建的对象BufferedImage导致后续显示损坏; 如果我评论这一行,一切正常.
以下是JScrollNavigator被覆盖的paintComponent方法:
@Override
protected void paintComponent(Graphics g) {
Component view = jScrollPane.getViewport().getView();
BufferedImage img = new BufferedImage(view.getWidth(), view.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
// Paint JScrollPane view to off-screen image and then scale.
// It is this action that causes the display corruption!
view.paint(g2d);
g2d.drawImage(img, 0, 0, null);
Image scaled = img.getScaledInstance(getWidth(), getHeight(), 0);
super.paintComponent(g);
g.drawImage(scaled, 0, 0, null);
}
Run Code Online (Sandbox Code Playgroud)
有没有人对腐败的原因有任何建议?我原本以为绘画到幕外图像应该对现有的绘画操作没有影响.
编辑 …
这是绘制椭圆形的简单示例.
public class SwingPainter extends JFrame{
public SwingPainter() {
super("Swing Painter");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
getContentPane().add(new MySwingComponent());
setSize(200, 200);
setVisible(true);
}
public static void main(String[] args) {
new SwingPainter();
}
class MySwingComponent extends JComponent {
public void paintComponent(Graphics g) {
System.out.println("paintComponent");
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(10, 10, 50, 50);
}
@Override
protected void paintBorder(Graphics g) {
System.out.println("Paint border");
super.paintBorder(g);
}
@Override
protected void paintChildren(Graphics g) {
System.out.println("Paint children");
super.paintChildren(g);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是在调试模式或在绘制之前向控制台添加一些信息(如示例中),您可以看到swing绘制组件两次.
的paintComponent
油漆边框
画儿童
的paintComponent
油漆边框
画儿童
我无法理解它为什么会发生,但我认为它会影响困难的GUI中的性能.
我正在使用javax.swing.Timer来安排和运行事件.但它似乎冻结了GUI.只是想知道这些事件是在单独的线程上运行还是我必须自己完成.
谢谢
我正在使用Java2D进行我正在编写的游戏,并且在我开始将其与其他swing组件集成之前没有遇到任何问题.我的问题是当我添加到JFrame的第一个组件不是我正在绘制的画布时,当我将鼠标悬停在文本窗格的滚动条上时,我会看到一个奇怪的神器.每次执行应用程序时都会发生这种情况.当我第一次使用画布时,没有问题.
出于某种原因,这似乎只发生在Windows上,当使用默认的Java2D管道时(恰好是sun.java2d.d3d = true),并且会发生工件.当我设置sun.java2d.opengl = true或sun.java2d.noddraw = false AND sun.java2d.d3d = false时,它不会发生.
我猜这是Direct3D Java2D管道的某种错误?我可以轻松地解决它,但很想知道是否有其他人遇到过这样的问题?我正在运行最新的JDK7u7,但它也适用于以前的版本.我应该注意,如果我最小化窗口并恢复它,那么工件就会消失,并且在我重新启动应用程序之前永远不会返回.
有神器:

没有工件(首先添加画布而不是JLabel图像):

如果有人对此有任何进一步的信息,我会很感激.谢谢!
我最近和我的挥杆问题有关.一切正常,直到我从JButton触发工具提示.之后将鼠标移动到ui的其余部分会导致奇怪的伪像和故障.
我无法显示整个代码,因为它太多但在这里我初始化按钮:
GridBagConstraints bottompane_gbc = new GridBagConstraints();
toggleTorConnectionButton = new JButton();
toggleTorConnectionButton.setToolTipText("Toggles Tor Connection.");
toggleTorConnectionButton.setIcon(new ImageIcon(ResourceHandler.Menueicon3_1));
toggleTorConnectionButton.setMinimumSize(new Dimension(removeFinishedDownloads.getMinimumSize().width, toggleTorConnectionButton.getIcon().getIconHeight()+5));
toggleTorConnectionButton.addActionListener(); // unimportant
bottompane_gbc.gridy = 1;
bottompane_gbc.fill = GridBagConstraints.BOTH;
bottompane_gbc.insets = new Insets(0,15,10,5);
bottompane.add(ToggleTorConnectionButton,bottompane_gbc);
this.add(bottompane,BorderLayout.PAGE_END);
Run Code Online (Sandbox Code Playgroud)
如果有人需要更多的信息来帮助我请随意问.我有点绝望.XD
编辑:经过一些修补我猜测问题与swing和我的使用有关.目前我使用很多Eventlisteners(这是不是很糟糕?),这可能会减慢awt线程?以下是HPROF的简要摘录:http: //www.pastebucket.com/96444
编辑2:我能够在一个方便而简单的例子中重新创建错误.当你移动按钮时,等待工具提示,然后在ui上.你会看到鬼影:(.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
public class Main_frame {
public static void main(String[] args) {
new Main_frame();
}
public Main_frame() {
JFrame frame = new JFrame("LOL"); …Run Code Online (Sandbox Code Playgroud)