我正在尝试制作一个简单的文字处理程序,其中 JFrame 顶部有一个 ControlPanel,中间有一个带有 JTextArea 组件的 TextPanel。我的程序的基本概述是,有一个名为 MyPanel 的 JPanel,它占据整个 JFrame 并保存其余的面板。 MyPanel 内部是 ControlPanel 和 TextPanel(不嵌套)。 ControlPanel 包含各种用于字体样式的 JButton 和 JComboBox,而 TextPanel 仅具有 JTextArea。
我想要的是,当我按下 ControlPanel 类中的 JButton(例如 BOLD)时,它将转到 actionPerformed() 并执行“text.repaint”。但我发现 text.repaint 甚至不会进入 TextPanel,也不会进入 PaintComponent 方法。我尝试将 ControlPanel 嵌套在 TextPanel 中并给它一个 BorderLayout.NORTH,效果很好,但似乎纸张连接到了控制面板,这是我不喜欢的。
有人可以给我一个替代方案或解释为什么 text.repaint() 不起作用吗?
这是我的代码的重要部分供引用:(重要部分用//标记)
注意:类 ControlPanel 和类 TextPanel 未对齐,因为我懒得在平庸的文本编辑器上修复对齐方式。相信我,它们不是嵌套的,并且都在 MyPanel 类中
class ControlPanel extends JPanel implements ActionListener
{
JButton bold, italics;
JComboBox font;
JComboBox size;
String [] fontsizes = {"8", "10", "12", "16", "20", "24", "36", "48", "56", "72"};
String [] fonttypes = {"Arial", "Serif", "Sans Serif", "Gothic", "Helvetica", "Times New Roman", "Comic Sans"};
public ControlPanel() // class ControlPanel control
{
setBackground(Color.gray);
this.setLayout(new FlowLayout());
Font boldfont = new Font("Serif", Font.BOLD, 16);
bold = new JButton("B");
bold.setFont(boldfont);
//bold.getModel().setPressed(true);
bold.addActionListener(this);
this.add(bold);
Font italicsfont = new Font("Serif", Font.ITALIC, 16);
italics = new JButton("I");
italics.setFont(italicsfont);
//italics.getModel().setPressed(true);
italics.addActionListener(this);
this.add(italics);
font = new JComboBox(fonttypes);
font.setSelectedIndex(0);
font.addActionListener(this);
this.add(font);
size = new JComboBox(fontsizes);
size.setSelectedIndex(2);
size.addActionListener(this);
size.setEditable(true);
this.add(size);
}
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
if (command.equals("B"))
{
if (boldfont)
boldfont = false;
else
boldfont = true;
}
if (command.equals("I"))
{
if (italicsfont)
italicsfont = false;
else
italicsfont = true;
}
fontselection = (String)font.getSelectedItem();
sizeselection = Integer.parseInt((String)(size.getSelectedItem()));
text.repaint(); // repaints TextPanel text class
}
}
class TextPanel extends JPanel // class TextPanel text
{
JTextArea type;
public TextPanel()
{
this.setLayout(new BorderLayout());
type = new JTextArea();
type.setEditable(true);
type.setLineWrap(true);
type.setWrapStyleWord(true);
type.setTabSize(4);
type.setMargin(new Insets(80, 100, 80, 100));
this.add(type, BorderLayout.CENTER);
}
public void paintComponent(Graphics g) // paintComponent() method for TextPanel
{
System.out.println("paintComponent of text"); // does not print out in terminal
super.paintComponent(g);
Font regfont;
int fontstyle = 0;
regfont = new Font("Arial", Font.PLAIN, 12);
if (boldfont)
{
fontstyle = 1;
}
else if (!boldfont)
{
fontstyle = 0;
}
if (italicsfont)
{
if (boldfont)
fontstyle = 3;
else
fontstyle = 2;
}
else if (!italicsfont)
{
if (boldfont)
fontstyle = 1;
else
fontstyle = 0;
}
regfont = new Font(fontselection, fontstyle, sizeselection);
type.setFont(regfont);
}
}
最佳答案
您的paint
方法没有为整个应用程序添加任何功能。实际上,您最好允许控制 Pane 将状态请求传递给 TextPane
,然后直接影响文本区域。
基本上,您在 paintComponent
方法中所做的操作对于您正在尝试的操作来说是错误的方法,并且实际上可能会产生循环重绘调用场景,从而消耗您的 CPU
已更新示例
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestTextPane01 {
public static void main(String[] args) {
new TestTextPane01();
}
public TestTextPane01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
TextPanel textPanel = new TextPanel();
ControlPanel controlPanel = new ControlPanel(textPanel);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(controlPanel, BorderLayout.NORTH);
frame.add(textPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class ControlPanel extends JPanel implements ActionListener {
JButton bold, italics;
JComboBox font;
JComboBox size;
String[] fontsizes = {"8", "10", "12", "16", "20", "24", "36", "48", "56", "72"};
String[] fonttypes = {"Arial", "Serif", "Sans Serif", "Gothic", "Helvetica", "Times New Roman", "Comic Sans"};
private boolean boldfont;
private boolean italicsfont;
private String fontselection;
private int sizeselection;
private TextPanel textPane;
public ControlPanel(TextPanel txtPanel) // class ControlPanel control
{
textPane = txtPanel;
setBackground(Color.gray);
this.setLayout(new FlowLayout());
Font boldfont = new Font("Serif", Font.BOLD, 16);
bold = new JButton("B");
bold.setFont(boldfont);
//bold.getModel().setPressed(true);
bold.addActionListener(this);
this.add(bold);
Font italicsfont = new Font("Serif", Font.ITALIC, 16);
italics = new JButton("I");
italics.setFont(italicsfont);
//italics.getModel().setPressed(true);
italics.addActionListener(this);
this.add(italics);
font = new JComboBox(fonttypes);
font.setSelectedIndex(0);
font.addActionListener(this);
this.add(font);
size = new JComboBox(fontsizes);
size.setSelectedIndex(2);
size.addActionListener(this);
size.setEditable(true);
this.add(size);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("B")) {
boldfont = !boldfont;
} else if (command.equals("I")) {
italicsfont = !italicsfont;
}
fontselection = (String) font.getSelectedItem();
sizeselection = Integer.parseInt((String) (size.getSelectedItem()));
// text.repaint(); // repaints TextPanel text class
textPane.setFont(boldfont, italicsfont);
}
}
class TextPanel extends JPanel // class TextPanel text
{
JTextArea type;
public TextPanel() {
this.setLayout(new BorderLayout());
type = new JTextArea();
type.setEditable(true);
type.setLineWrap(true);
type.setWrapStyleWord(true);
type.setTabSize(4);
type.setMargin(new Insets(80, 100, 80, 100));
this.add(type, BorderLayout.CENTER);
}
public void setFont(boolean boldFont, boolean italicsFont) {
Font font = type.getFont();
int style = Font.PLAIN;
if (boldFont && italicsFont) {
style = Font.BOLD | Font.ITALIC;
} else if (boldFont) {
style = Font.BOLD;
} else if (italicsFont) {
style = Font.ITALIC;
}
font = font.deriveFont(style);
System.out.println("Font");
type.setFont(font);
}
}
}
我还建议您阅读 How to Use Scroll Panes , Performing Custom Painting和 Painting in AWT and Swing
关于java - 不同类之间的Repaint()不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15848242/