我正在开发一个相对复杂的java项目,该项目涉及GUI以及通过网络与两个不同的arduinos进行通信。
我在其中一个arduinos上有一个旋转编码器,可以告诉java程序车轮转了多远。我有一个线程,处理从arduino检索数据和旋转图像。
当我尝试快速旋转旋转编码器时出现问题。 图像将闪烁白色,如here所示。
我使用以下代码旋转图像:
public static void setimageto(int degree){
stageRotation.stageangel = degree;
try {
BufferedImage localBufferedImage = ImageIO.read(new File("CircleStagePNG.png"));
JPanel rotatepanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
if (g != null) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.toRadians(degree), localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
g2.drawImage(localBufferedImage, 0, 0, null);
}
}
};
stageRotation.pnPanel3.removeAll();
rotatepanel.setBackground(stageRotation.color);
stageRotation.pnPanel3.add(rotatepanel);
stageRotation.pnPanel0.setBackground(stageRotation.color);
stageRotation.pnPanel0.updateUI();
} catch (IOException localIOException) {
}
}
我还将完整代码上传到此link
主要的java文件名为 stageRotation.java ,而 javatest.java 应该是它应该是什么样子的示例。
任何解释或解决方案都会有所帮助,因为任何建议都会使这个问题更加用户友好。
[编辑] 这是我的主类和构造函数,删除了大量代码。我试图尽可能缩短它,但可能留下了一些不必要的物品,这也是它可能无法正常运行的原因。再次感谢您的帮助
import javax.swing.UIManager.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.net.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.net.ServerSocket;
import javax.swing.filechooser.*;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.concurrent.TimeUnit;
public class stageRotation extends JPanel {
static stageRotation thestageRotation;
public static JFrame mainFrame;
public static JPanel pnPanel0;
public static JPanel pnPanel1;
public static JPanel pnPanel3;
public static Object rotationobject;
public static Object[] queadd;
public static Thread motorcontrollerthread;
public static Thread sensorcontrollerthread;
public static Thread rotationthread = new Thread();
public static Thread inputthread = new Thread();
public static Boolean endinsight = false;
public static Boolean rotaterflag = true;
public static Boolean imagechange = false;
public static volatile Boolean sensorinput = true;
public static volatile Boolean motorinput = true;
public static Color color = Color.WHITE;
public static PrintWriter motorsocketout;
public static PrintWriter sensorsocketout;
public static Socket echoSocket;
public static BufferedImage localBufferedImage;
public static void main(String[] args) {
//Makes the whole program look a lot better but there are some inexcusable errors that need to be worked out
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
thestageRotation = new stageRotation();
}
public stageRotation() {
/*while(motorconnected == 0 || sensorconnected == 0) {
if (motorconnected == -1 || sensorconnected == -1) {
System.exit(0);
}
}*/
//frame definition and layoutmanager definition
JFrame mainFrame = new JFrame("Que thingy");
pnPanel0 = new JPanel();
GridBagLayout localGridBagLayout1 = new GridBagLayout();
GridBagConstraints localGridBagConstraints1 = new GridBagConstraints();
pnPanel0.setLayout(localGridBagLayout1);
pnPanel3 = new JPanel();
pnPanel3.setLayout(localGridBagLayout1);
// create image for display
try {
final BufferedImage localBufferedImage = ImageIO.read(new File("CircleStagePNG.png"));
pnPanel1 = new JPanel() {
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
protected void paintComponent(Graphics paramAnonymousGraphics) {
super.paintComponent(paramAnonymousGraphics);
Graphics2D localGraphics2D = (Graphics2D)paramAnonymousGraphics;
localGraphics2D.rotate(0.0D, localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
localGraphics2D.drawImage(localBufferedImage, 0, 0, null);
}
};
//set up graphical properties for image
GridBagLayout localGridBagLayout2 = new GridBagLayout();
pnPanel1.setBackground(color);
pnPanel3.add(pnPanel1);
pnPanel3.setLayout(localGridBagLayout2);
localGridBagConstraints1.gridx = 0;
localGridBagConstraints1.gridy = 0;
localGridBagConstraints1.gridwidth = 1;
localGridBagConstraints1.gridheight = 2;
localGridBagConstraints1.fill = GridBagConstraints.BOTH;
localGridBagConstraints1.weightx = 1;
localGridBagConstraints1.weighty = 1;
localGridBagConstraints1.anchor = GridBagConstraints.NORTH;
localGridBagLayout1.setConstraints(pnPanel3, localGridBagConstraints1);
pnPanel3.setBackground(Color.WHITE);
pnPanel0.add(pnPanel3);
mainFrame.setContentPane(pnPanel0);
mainFrame.pack();
mainFrame.setBackground(Color.WHITE);
mainFrame.setVisible(true);
tbJquetable.requestFocus();
} catch (IOException localIOException) {}
}
//changes background will sometimes report nullpointerexception error however has no effect on code
public static void setimageto(int degree){
stageRotation.stageangel = degree;
try {
localBufferedImage = ImageIO.read(new File("CircleStagePNG.png"));
pnPanel1 = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.toRadians(degree), localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
g2.drawImage(localBufferedImage, 0, 0, null);
}
};
stageRotation.pnPanel3.removeAll();
pnPanel1.setBackground(stageRotation.color);
stageRotation.pnPanel3.add(pnPanel1);
stageRotation.pnPanel0.setBackground(stageRotation.color);
stageRotation.pnPanel0.updateUI();
} catch (IOException localIOException) {
}
}
}
[EDIT2]
虽然以下代码不会闪烁,但图像会在点处挂起。我无法使用url imagaes重现闪烁,只能使用本地文件;但是,我认为图像悬挂和闪烁是同样的问题。
import javax.swing.UIManager.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.net.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.net.ServerSocket;
import javax.swing.filechooser.*;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.concurrent.TimeUnit;
public class stageRotation extends JPanel {
static stageRotation thestageRotation;
public static JFrame mainFrame;
public static JPanel pnPanel0;
public static JPanel pnPanel1;
public static JPanel pnPanel3;
public static Object rotationobject;
public static Object[] queadd;
public static Thread motorcontrollerthread;
public static Thread sensorcontrollerthread;
public static Thread rotationthread = new Thread();
public static Thread inputthread = new Thread();
public static Boolean endinsight = false;
public static Boolean rotaterflag = true;
public static Boolean imagechange = false;
public static volatile Boolean sensorinput = true;
public static volatile Boolean motorinput = true;
public static Color color = Color.WHITE;
public static PrintWriter motorsocketout;
public static PrintWriter sensorsocketout;
public static Socket echoSocket;
public static BufferedImage localBufferedImage;
public static URL url;
public static void main(String[] args) {
//Makes the whole program look a lot better but there are some inexcusable errors that need to be worked out
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
thestageRotation = new stageRotation();
for (int i = 0; i < 360; i++){
setimageto(i);
}
}
public stageRotation() {
try{
url = new URL("https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/CIRCLE_LINES.svg/220px-CIRCLE_LINES.svg.png");
} catch(MalformedURLException a){}
JFrame mainFrame = new JFrame("Que thingy");
pnPanel0 = new JPanel();
GridBagLayout localGridBagLayout1 = new GridBagLayout();
GridBagConstraints localGridBagConstraints1 = new GridBagConstraints();
pnPanel0.setLayout(localGridBagLayout1);
pnPanel3 = new JPanel();
pnPanel3.setLayout(localGridBagLayout1);
// create image for display
try {
final BufferedImage localBufferedImage = ImageIO.read(url);
pnPanel1 = new JPanel() {
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
protected void paintComponent(Graphics paramAnonymousGraphics) {
super.paintComponent(paramAnonymousGraphics);
Graphics2D localGraphics2D = (Graphics2D)paramAnonymousGraphics;
localGraphics2D.rotate(0.0D, localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
localGraphics2D.drawImage(localBufferedImage, 0, 0, null);
}
};
//set up graphical properties for image
GridBagLayout localGridBagLayout2 = new GridBagLayout();
pnPanel1.setBackground(color);
pnPanel3.add(pnPanel1);
pnPanel3.setLayout(localGridBagLayout2);
localGridBagConstraints1.gridx = 0;
localGridBagConstraints1.gridy = 0;
localGridBagConstraints1.gridwidth = 1;
localGridBagConstraints1.gridheight = 2;
localGridBagConstraints1.fill = GridBagConstraints.BOTH;
localGridBagConstraints1.weightx = 1;
localGridBagConstraints1.weighty = 1;
localGridBagConstraints1.anchor = GridBagConstraints.NORTH;
localGridBagLayout1.setConstraints(pnPanel3, localGridBagConstraints1);
pnPanel3.setBackground(Color.WHITE);
pnPanel0.add(pnPanel3);
mainFrame.setExtendedState(6);
WindowListener exitListener = new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
System.out.println("EXIT");
stageRotation.motorsocketout.println("EXIT");
sensorsocketout.println("EXIT");
sensorinput = false;
motorinput = false;
mainFrame.setVisible(false);
mainFrame.dispose();
System.exit(0);
} catch (NullPointerException p){
System.exit(0);
}
}
};
mainFrame.addWindowListener(exitListener);
mainFrame.setContentPane(pnPanel0);
mainFrame.pack();
mainFrame.setBackground(Color.WHITE);
mainFrame.setVisible(true);
} catch (IOException localIOException) {}
}
//changes background will sometimes report nullpointerexception error however has no effect on code
public static void setimageto(int degree){
try {
localBufferedImage = ImageIO.read(url);
pnPanel1 = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.toRadians(degree), localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
g2.drawImage(localBufferedImage, 0, 0, null);
}
};
stageRotation.pnPanel3.removeAll();
pnPanel1.setBackground(stageRotation.color);
stageRotation.pnPanel3.add(pnPanel1);
stageRotation.pnPanel0.setBackground(stageRotation.color);
stageRotation.pnPanel0.updateUI();
} catch (IOException localIOException) {
}
}
}
答案 0 :(得分:2)
好的..上面的MCVE表现出各种各样的误解。
Timer
。然后ActionListener
(在计时器的构造函数中使用)应该执行动画的单个帧。通常使用循环来设置动画将阻止事件调度线程,最终结果是“动画”和“动画”。将仅显示为第一帧 - 直接切换到最后一帧。可能对代码进行了许多其他改进,但我停在那里,因为它似乎解决了主要问题。
以下是实现上述建议的代码:
import javax.swing.UIManager.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class stageRotation extends JPanel {
private static stageRotation thestageRotation;
public static JPanel pnPanel0;
public static PnPanel1 pnPanel1;
public static JPanel pnPanel3;
public static volatile Boolean sensorinput = true;
public static volatile Boolean motorinput = true;
public static Color color = Color.WHITE;
public static PrintWriter motorsocketout;
public static PrintWriter sensorsocketout;
public static BufferedImage localBufferedImage;
public static URL url;
public static void main(String[] args) {
//Makes the whole program look a lot better but there are some inexcusable errors that need to be worked out
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
setThestageRotation(new stageRotation());
ActionListener actionListener = new ActionListener() {
int degree = 0;
@Override
public void actionPerformed(ActionEvent e) {
if (degree<360) {
degree++;
setimageto(degree);
}
}
};
Timer timer = new Timer(10,actionListener);
timer.start();
}
/**
* @param aThestageRotation the thestageRotation to set
*/
public static void setThestageRotation(stageRotation aThestageRotation) {
thestageRotation = aThestageRotation;
}
public stageRotation() {
try {
url = new URL("https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/CIRCLE_LINES.svg/220px-CIRCLE_LINES.svg.png");
localBufferedImage = ImageIO.read(url);
} catch (Exception ex) {
Logger.getLogger(stageRotation.class.getName()).log(Level.SEVERE, null, ex);
}
JFrame mainFrame = new JFrame("Que thingy");
pnPanel0 = new JPanel();
GridBagLayout localGridBagLayout1 = new GridBagLayout();
GridBagConstraints localGridBagConstraints1 = new GridBagConstraints();
pnPanel0.setLayout(localGridBagLayout1);
pnPanel3 = new JPanel();
pnPanel3.setLayout(localGridBagLayout1);
pnPanel1 = new PnPanel1();
pnPanel3.add(pnPanel1);
// create image for display
try {
final BufferedImage localBufferedImage = ImageIO.read(url);
//set up graphical properties for image
GridBagLayout localGridBagLayout2 = new GridBagLayout();
pnPanel1.setBackground(color);
pnPanel3.setLayout(localGridBagLayout2);
localGridBagConstraints1.gridx = 0;
localGridBagConstraints1.gridy = 0;
localGridBagConstraints1.gridwidth = 1;
localGridBagConstraints1.gridheight = 2;
localGridBagConstraints1.fill = GridBagConstraints.BOTH;
localGridBagConstraints1.weightx = 1;
localGridBagConstraints1.weighty = 1;
localGridBagConstraints1.anchor = GridBagConstraints.NORTH;
localGridBagLayout1.setConstraints(pnPanel3, localGridBagConstraints1);
pnPanel3.setBackground(Color.WHITE);
pnPanel0.add(pnPanel3);
WindowListener exitListener = new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
System.out.println("EXIT");
stageRotation.motorsocketout.println("EXIT");
sensorsocketout.println("EXIT");
sensorinput = false;
motorinput = false;
mainFrame.setVisible(false);
mainFrame.dispose();
System.exit(0);
} catch (NullPointerException p) {
System.exit(0);
}
}
};
mainFrame.addWindowListener(exitListener);
mainFrame.setContentPane(pnPanel0);
mainFrame.pack();
mainFrame.setBackground(Color.WHITE);
mainFrame.setVisible(true);
} catch (IOException localIOException) {
}
}
//changes background will sometimes report nullpointerexception error however has no effect on code
public static void setimageto(int degree) {
pnPanel1.setDegree(degree);
pnPanel1.repaint();
}
class PnPanel1 extends JPanel {
int degree;
@Override
public Dimension getPreferredSize() {
return new Dimension(localBufferedImage.getWidth(), localBufferedImage.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.toRadians(degree), localBufferedImage.getWidth() / 2, localBufferedImage.getHeight() / 2);
g2.drawImage(localBufferedImage, 0, 0, this);
}
public void setDegree(int degree) {
this.degree = degree;
}
};
}
答案 1 :(得分:1)
我认为问题是针对每个学位的变化,你正在清除stageRotation并重新设置背景。
您应该只调用所有初始化代码一次,只有在需要更改学位时才重绘图像。