我正在尝试制作一个简单的文字处理器,其中在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
方法没有为整个应用程序添加任何功能。实际上,最好允许控制面板将状态请求传递给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