2013-04-06 53 views
2

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

回答

2

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 PanesPerforming Custom PaintingPainting in AWT and Swing

+0

讀THANK YOU SO MUCH!它工作完美,我想我明白了一切。我只有幾個一般問題: 您認爲使用繪畫方法的時候可以嗎? 爲什麼您將布爾值boldfont和italicsfont傳遞給setFont()時它們已經是可訪問的變量了?這僅僅是個人喜好嗎?還是僅僅是一個好習慣? 再次感謝! – applemavs 2013-04-07 05:11:24

+0

我可能選擇重寫'paint'的唯一可能原因是,如果我想繪製組件的頂部和它的所有子組件,但這很容易被重繪管理器覆蓋,他們可以選擇不重繪容器(導致孩子們在上面)。我將'boolean'標誌傳遞給'TextPane'的原因是因爲TextPane負責管理這些標誌,沒有其他人。這也意味着我隔離可能發生更新的位置。所以改變的唯一方法就是通過'setFont'方法 – MadProgrammer 2013-04-07 06:36:46

+0

我應該加上,如果打算重寫'paint',我可能會考慮使用類似JXLayer或GlassPane的東西 – MadProgrammer 2013-04-07 07:01:13

相關問題