我正在试图制作一个简单的文字处理器,其中JFrame的顶部有一个ControlPanel,而JTextArea组件的中心有一个TextPanel。我的程序的基本概述是有一个名为MyPanel的JPanel,它占用了整个JFrame并保留了其余的面板。 MyPanel内部是ControlPanel和TextPanel(不嵌套)。 ControlPanel包含用于字体样式的各种JButton和JComboBoxes,而TextPanel仅包含JTextArea。不同类之间的repaint()不更新
我想要的是,当我按下ControlPanel类中的JButton(例如BOLD)时,它将转到actionPerformed()并执行“text.repaint”。但是我发现text.repaint甚至没有进入TextPanel,也没有进入paintComponent方法。我尝试在TextPanel中嵌套ControlPanel并给它一个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);
}
}
读THANK YOU SO MUCH!它工作完美,我想我明白了一切。我只有几个一般问题: 您认为使用绘画方法的时候可以吗? 为什么您将布尔值boldfont和italicsfont传递给setFont()时它们已经是可访问的变量了?这仅仅是个人喜好吗?还是仅仅是一个好习惯? 再次感谢! – applemavs 2013-04-07 05:11:24
我可能选择重写'paint'的唯一可能原因是,如果我想绘制组件的顶部和它的所有子组件,但这很容易被重绘管理器覆盖,他们可以选择不重绘容器(导致孩子们在上面)。我将'boolean'标志传递给'TextPane'的原因是因为TextPane负责管理这些标志,没有其他人。这也意味着我隔离可能发生更新的位置。所以改变的唯一方法就是通过'setFont'方法 – MadProgrammer 2013-04-07 06:36:46
我应该加上,如果打算重写'paint',我可能会考虑使用类似JXLayer或GlassPane的东西 – MadProgrammer 2013-04-07 07:01:13