我正在試圖製作一個簡單的文字處理器,其中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