2013-04-06 50 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

相关问题