好的,所以我有一个程序,在 JPanel 上显示一个字符串,它绘制上升位置的线条,它在下降位置和中间位置以及四分之一位置处绘制一条线。我有一个组合框来更改字符串的字体和大小,并且我有一个 JTextField 来更改文本本身。我使用actionListeners 来更新字符串。每当我通过 JTextField 更新字符串的文本时,程序就会出现故障,并在 JFrame 的右上角显示 JTextField 图像的副本。
代码:
package com.Patel.RichClients;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
//a class to demonstrate
public class StringAscent extends JFrame {
private static Font font;
private int fontSize = 50;
private StringPanel panel;
private JComboBox fontOptions;
private JComboBox fontSizeOptions;
private JTextField text;
// constructor
public StringAscent() {
// set the initial font to Times new Roman
font = new Font("Agency FB", Font.PLAIN, fontSize);
setVisible(true);
setSize(520, 170);
setTitle("String Ascents");
setLayout(new BorderLayout());
//set up the components
GraphicsEnvironment ge= GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontNames = ge.getAvailableFontFamilyNames();
fontOptions = new JComboBox(fontNames);
text = new JTextField(22);
text.setText("Swing");
String[] sizeOptions = new String[50];
for (int i = 0; i < sizeOptions.length; i ++){
sizeOptions[i] = Integer.toString(i + 1);
}
fontSizeOptions = new JComboBox(sizeOptions);
panel = new StringPanel();
//set up actionListeners
fontOptions.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JComboBox ref = (JComboBox) e.getSource();
font = new Font(fontNames[ref.getSelectedIndex()], Font.PLAIN, fontSize);
panel.repaint();
}
});
fontSizeOptions.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
JComboBox ref = (JComboBox) e.getSource();
fontSize = Integer.parseInt(sizeOptions[ref.getSelectedIndex()]);
font = new Font(font.getName(), Font.PLAIN, fontSize);
panel.repaint();
}
});
text.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
panel.repaint();
}
});
//add components
add(panel, BorderLayout.NORTH);
add(fontOptions, BorderLayout.WEST);
add(text, BorderLayout.CENTER);
add(fontSizeOptions, BorderLayout.EAST);
}
public static void main(String[] args) {
Runnable showGui = new Runnable() {
public void run() {
StringAscent gui = new StringAscent();
}
};
SwingUtilities.invokeLater(showGui);
}
// inner JPanel class
private class StringPanel extends JPanel {
// constructor
public StringPanel() {
}
public Dimension getPreferredSize() {
return new Dimension(400, 100);
}
public void paintComponent(Graphics g) {
g.setColor(Color.black);
// set up the string
g.setFont(font);
// FontMetric is an object that holds information relevant to the
// rendering of the font
FontMetrics metric = g.getFontMetrics();
int ascent = metric.getAscent();
String string = text.getText();
g.drawString(string, 100, 50);
int x = 50;
// draw Ascent line
g.drawLine(x, 50 - ascent, x + 180, 50 - ascent);
// draw Ascent/2 line
g.drawLine(x, 50 - (ascent / 2), x + 180, 50 - (ascent / 2));
// draw Ascent/4 line
g.drawLine(x, 50 - (ascent / 4), x + 180, 50 - (ascent / 4));
// draw baseline line
g.drawLine(x, 50, x + 180, 50);
// draw Descent line
g.drawLine(x, 50 + metric.getDescent(), x + 180, 50 + metric.getDescent());
}
}
}
最佳答案
将 super.paintComponent(g)
添加到 paintComponent
方法的开头
public void paintComponent(Graphics g) {
super.paintComponent(g)
g.setColor(Color.black);
//...
基本上,paintComponent
的工作之一是准备用于绘制当前组件的Graphics
上下文。在 Swing 中,Graphics
是一种共享资源,在绘制时由窗口内的所有组件使用,因此在绘制之前确保正确准备好上下文非常重要
看看Performing Custom Painting和 Painting in AWT and Swing有关绘画工作原理的更多详细信息
关于java - JTextField 出现故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36322627/