我写了一个快速测试程序,它接受一个字符串输入并在JFrame上绘制它。超级简单。但出于某种原因,该计划并不是一致的。如同输入一样,它并不总是将字符串绘制到屏幕上。为了尝试和调试,我添加了一个repaint(); to paintComponent(反复要求绘制输入,因此我添加了双缓冲区)。当程序决定不绘制到框架时,它没有使它重绘();并且没有显示新的输入对话框。我无法理解为什么。
package test;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class Main extends JFrame {
private Image dbImage;
private Graphics dbg;
public Main() {
setTitle("Test Project");
setSize(300, 300);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g) {
g.drawString(input(), 140, 130);
}
public static String input() {
String x = ((String)JOptionPane.showInputDialog (
null, "Enter a string", "Test Project",
JOptionPane.QUESTION_MESSAGE,
null, null, null));
return x;
}
public static void main(String[] args) {
Main main = new Main();
}
}
一个注意事项:最初,输入法是在一个单独的类中,因为这就是我正在测试它的项目。为了简洁起见,我把它移到这里,因为无论方法在哪里,问题仍然会出现。
答案 0 :(得分:2)
从我的评论中得出理论:-)
为我的评论添加更多积分:
setSize()
上使用JFrame
,而是覆盖getPreferredSize()
方法,而不是您扩展的任何JComponent/JPanel
。现在只需在pack()
上调用JFrame
,就可以计算出自己的大小。以下是我所说的实例:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JPanel {
private JButton button;
private String message;
private ActionListener buttonAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
message = input();
repaint();
}
};
public Main() {
message = "Nothing to display yet...";
}
private void displayGUI() {
JFrame frame = new JFrame("Painting Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
button = new JButton("Get Message");
button.addActionListener(buttonAction);
contentPane.add(this, BorderLayout.CENTER);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
@Override
public Dimension getPreferredSize() {
return (new Dimension(200, 200));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(message, 50, 50);
}
public String input() {
String x = ((String)JOptionPane.showInputDialog (
null, "Enter a string", "Test Project",
JOptionPane.QUESTION_MESSAGE,
null, null, null));
return x;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Main().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
如果您不想使用JButton
来提问,可以在MouseListener
上添加JPanel
,如下图所示:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JPanel {
private String message;
private int x;
private int y;
private MouseAdapter mouseAction = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me) {
message = input();
x = me.getX();
y = me.getY();
repaint();
}
};
public Main() {
message = "Nothing to display yet...";
x = y = 0;
}
private void displayGUI() {
JFrame frame = new JFrame("Painting Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
addMouseListener(mouseAction);
contentPane.add(this, BorderLayout.CENTER);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
@Override
public Dimension getPreferredSize() {
return (new Dimension(200, 200));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(message, x, y);
}
public String input() {
String x = ((String)JOptionPane.showInputDialog (
null, "Enter a string", "Test Project",
JOptionPane.QUESTION_MESSAGE,
null, null, null));
return x;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Main().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
答案 1 :(得分:2)
你的代码有很多问题,我写了一个新程序来做同样的事情。我确实保留了你的输入法。
我建议你花一点时间研究Oracle Swing Tutorial。
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SimpleInput implements Runnable {
@Override
public void run() {
JFrame frame = new JFrame("String Display");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
DrawingPanel drawingPanel = new DrawingPanel();
frame.add(drawingPanel);
frame.pack();
frame.setVisible(true);
new Thread(new DisplayRunnable(drawingPanel)).start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new SimpleInput());
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 7580353846463376668L;
private String text;
public DrawingPanel() {
this.setPreferredSize(new Dimension(300, 200));
this.text = " ";
}
public void setText(String text) {
this.text = text;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout layout = new TextLayout(text, g.getFont(), frc);
Rectangle2D bounds = layout.getBounds();
int width = (int) Math.round(bounds.getWidth());
int height = (int) Math.round(bounds.getHeight());
int x = (getWidth() - width) / 2;
int y = height + (getHeight() - height) / 2;
layout.draw(g2d, (float) x, (float) y);
}
}
public class DisplayRunnable implements Runnable {
private String displayString = " ";
private DrawingPanel drawingPanel;
public DisplayRunnable(DrawingPanel drawingPanel) {
this.drawingPanel = drawingPanel;
}
@Override
public void run() {
long sleep = 5L;
while ((displayString != null) && (!displayString.equals(""))) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
drawingPanel.setText(displayString);
drawingPanel.repaint();
}
});
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
}
displayString = input();
sleep = 3000L;
}
}
public String input() {
String x = ((String) JOptionPane.showInputDialog(drawingPanel,
"Enter a string", "Test Project", JOptionPane.QUESTION_MESSAGE,
null, null, null));
return x;
}
}
}