0

我知道这个问题已经被问过好几次了。我正在尝试从另一个类刷新我的 JTextPane,当我从我的主类执行它时,它可以工作,但任何其他类都没有。我听说你需要使用线程来做到这一点,但我还没有真正看到有人实现它。我尽可能简单地在下面提供了我的代码。有3个班。谢谢!

这是它的输出:http: //imgur.com/fQVDFPk

______________________________________________________
public class frame extends JPanel implements Runnable {

public TextBox textbox = new TextBox();

        Thread t1 = new Thread(new TextBox());

    public void run(){

    }
    public frame(){     

        t1.start();
        textField();

    }
public void textField(){
    add(textbox.sp);          
}

}

___________________________________________________

//bunch of imports

public class TextBox implements Runnable {

        JTextPane field = new JTextPane();
        JScrollPane sp = new JScrollPane(field);
        String name ="This is your message!!\n\n Message \n\n Message";
        public void run(){    

        try{
            Thread.sleep(2000);
                   System.out.println("hello thread");                                                             
            }catch(Exception e){}
         }            

    public TextBox(){
        field.setText("Welcome to Stack Overflow!!\n");  
        Message();
        }
    public void Message(){
                Style style = field.addStyle("I'm a Style", null);
                            StyledDocument doc = field.getStyledDocument();
                            StyleConstants.setForeground(style, Color.BLACK);
                            field.setCaretPosition(field.getText().length());                                    
                            try { doc.insertString(doc.getLength(), GetText(),style); }
                                    catch (BadLocationException e){} 
   Color color=new Color(255,255,255); 
   field.setBackground(color);  
   sp.setBounds(100, 335, 350, 100);
   field.setEditable(false);
   sp.setAutoscrolls(true);
    }
    public String GetText ( )
    {
        return name;
    }
    public void SetText (String PassedText)
    {
        name = PassedText;           
    }
}

//我创建了一个新类来演示当我更改文档时我想要做什么。


public class ChangePane {
     public TextBox textbox = new TextBox();
    ChangePane(){

    Style style = textbox.field.addStyle("I'm a Style", null);

    StyledDocument doc = textbox.field.getStyledDocument();

    try {doc.insertString(doc.getLength(), "TESTING     ADDITION",style);}catch(BadLocationException e){}

    textbox.Message();
    }

}
4

1 回答 1

5

我正在尝试从另一个类刷新我的 JTextPane,

至于更新另一个类中的字段,您应该为保存该字段的类提供一个公共方法,其他类可以调用该方法来更改该字段的状态。例如,如果您想允许另一个类更改 a 中的文本,则为您JTextField的类提供如下方法:

public void setMyTextFieldText(String text) {
    myTextField.setText(text);

    // or if a JTextPane by inserting text into its Document here
}

这与 Swing 或 GUI 无关,而与基本的 Java 和面向对象的编码有关。对于 JTextPane,你需要做的不仅仅是 setText,我相信,但我不怎么使用它们。

当我从我的主课上做它时,它可以工作,但任何其他课程都没有。我听说你需要使用线程来做到这一点,但我还没有真正看到有人实现它。我尽可能简单地在下面提供了我的代码。

如果您从作为主要 Swing 线程的 EDT(事件调度线程)对 Swing GUI 进行更改,就会出现线程问题。如果发生这种情况,那么是的,您应该将 Swing 调用排队到 Swing 事件线程,方法是将其放入 Runnable 并放入 Swing 事件队列:

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    // your swing calls go here
  }
});

编辑1
注意,您的这种方法没有任何用处:

// you should rename this setText(String passedText)
public void SetText (String PassedText)
{
    name = PassedText;           
    // you need to change your JTextPane's Document in here *****
}

它所做的只是更改名称字符串字段引用的文本,但这不会更改任何显示的文本。您必须通过调用 JTextPane 方法,通过将文本插入 JTextPane 的文档来更改 JTextPane 文本。


编辑 2
请了解和使用 Java 命名约定,以免混淆可能想要理解您的代码并帮助您的人。类名应以大写字母开头,变量名和字段名应以小写字母开头。您的命名似乎是倒退的。


编辑 3
您知道这里有两个完全独立的 TextBox 对象:

public TextBox textbox = new TextBox();
Thread t1 = new Thread(new TextBox());

改变一个的状态不会影响另一个。

另外,为什么要让组件类实现 Runnable 然后将它们放入线程中。这没什么意义。要了解 Swing 线程,请阅读Swing 中的并发


编辑 4
一个sscce的例子:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.text.*;

public class TextBoxTest {
   private JPanel mainPanel = new JPanel();
   private MyTextBox myTextBox = new MyTextBox();
   private JTextArea textArea = new JTextArea(20, 30);

   @SuppressWarnings("serial")
   public TextBoxTest() {
      JScrollPane scrollPane = new JScrollPane(textArea);
      scrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("JTextArea"),
            scrollPane.getBorder()));

      JPanel centerPanel = new JPanel(new GridLayout(1, 0));
      centerPanel.add(myTextBox.getMainComponent());
      centerPanel.add(scrollPane);

      JPanel bottomPanel = new JPanel();
      bottomPanel.add(new JButton(new AbstractAction("Submit Text") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_S);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               myTextBox.setText(textArea.getText());
            } catch (BadLocationException e1) {
               e1.printStackTrace();
            }
         }
      }));
      bottomPanel.add(new JButton(new AbstractAction("Append Text") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_A);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               myTextBox.appendText(textArea.getText() + "\n");
            } catch (BadLocationException e1) {
               e1.printStackTrace();
            }
         }
      }));      
      bottomPanel.add(new JButton(new AbstractAction("Append Red Text") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_R);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               myTextBox.appendTextInRed(textArea.getText() + "\n");
            } catch (BadLocationException e1) {
               e1.printStackTrace();
            }
         }
      }));

      mainPanel.setLayout(new BorderLayout());
      mainPanel.add(centerPanel, BorderLayout.CENTER);
      mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private static void createAndShowGui() {
      TextBoxTest textBoxTester = new TextBoxTest();

      JFrame frame = new JFrame("TextBoxTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(textBoxTester.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyTextBox {
   private JTextPane textPane = new JTextPane();
   private JScrollPane scrollPane = new JScrollPane(textPane);
   private String name = "This is your message!! Message  Message "
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!! Message  Message "
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n";
   private StyledDocument doc = textPane.getStyledDocument();

   public MyTextBox() {
      addStylesToDocument(doc);
      textPane.setEditable(false);
      textPane.setFocusable(false);
      try {
         doc.insertString(0, name, doc.getStyle("regular"));
      } catch (BadLocationException e) {
         e.printStackTrace();
      }

      scrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("JTextPane"),
            scrollPane.getBorder()));
   }

   private void addStylesToDocument(StyledDocument doc2) {
      Style def = StyleContext.getDefaultStyleContext().getStyle(
            StyleContext.DEFAULT_STYLE);

      Style regular = doc.addStyle("regular", def);
      StyleConstants.setFontFamily(def, "SansSerif");
      StyleConstants.setFontSize(regular, 16);

      Style s = doc.addStyle("red", regular);
      StyleConstants.setForeground(s, Color.red);

   }

   public JScrollPane getMainComponent() {
      return scrollPane;
   }

   public void setText(String text) throws BadLocationException {
      doc.remove(0, doc.getLength());
      doc.insertString(0, text, doc.getStyle("regular"));
   }

   public void appendText(String text) throws BadLocationException {
      doc.insertString(doc.getLength(), text, doc.getStyle("regular"));
   }

   public void appendTextInRed(String text) throws BadLocationException {
      doc.insertString(doc.getLength(), text, doc.getStyle("red"));
   }

}

编辑 5
要从另一个线程发送,正如我在其他地方所指出的,只需将代码包装到 Runnable 中,然后通过SwingUtilities.invokeLater(myRunnable).

例如,我可以为 MyTextBox 类提供一个方法来完成所有这些操作,并且任何外部类都可以调用它:

public void appendTextOffEdt(final String text) {
  // first make sure that we're in fact off of the EDT
  if (SwingUtilities.isEventDispatchThread()) {
     try {
        appendTextInRedBold(text);
     } catch (BadLocationException e) {
        e.printStackTrace();
     }
  } else {
     SwingUtilities.invokeLater(new Runnable() {
        public void run() {
           try {
              appendTextInRedBold(text);
           } catch (BadLocationException e) {
              e.printStackTrace();
           }
        }
     });
  }
}

例如:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.text.*;

public class TextBoxTest {
   private JPanel mainPanel = new JPanel();
   private MyTextBox myTextBox = new MyTextBox();
   private JTextArea textArea = new JTextArea(20, 30);
   private SendTextOffEdt sendTextOffEdt = new SendTextOffEdt(myTextBox);

   @SuppressWarnings("serial")
   public TextBoxTest() {
      JScrollPane scrollPane = new JScrollPane(textArea);
      scrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("JTextArea"),
            scrollPane.getBorder()));

      JPanel centerPanel = new JPanel(new GridLayout(1, 0));
      centerPanel.add(myTextBox.getMainComponent());
      centerPanel.add(scrollPane);

      JPanel bottomPanel = new JPanel();

      new Thread(sendTextOffEdt).start();

      bottomPanel.add(new JButton(new AbstractAction("Append Text") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_A);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               myTextBox.appendText(textArea.getText() + "\n");
            } catch (BadLocationException e1) {
               e1.printStackTrace();
            }
         }
      }));
      bottomPanel.add(new JButton(new AbstractAction("Append Blue Text") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_B);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               myTextBox.appendTextInBlue(textArea.getText() + "\n");
            } catch (BadLocationException e1) {
               e1.printStackTrace();
            }
         }
      }));
      bottomPanel.add(new JButton(new AbstractAction("Exit") {
         {
            putValue(MNEMONIC_KEY, KeyEvent.VK_X);
         }

         @Override
         public void actionPerformed(ActionEvent e) {
            Window win = SwingUtilities.getWindowAncestor(mainPanel);
            win.dispose();
         }
      }));

      mainPanel.setLayout(new BorderLayout());
      mainPanel.add(centerPanel, BorderLayout.CENTER);
      mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
   }

   public JComponent getMainComponent() {
      return mainPanel;
   }

   private static void createAndShowGui() {
      TextBoxTest textBoxTester = new TextBoxTest();

      JFrame frame = new JFrame("TextBoxTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(textBoxTester.getMainComponent());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class SendTextOffEdt implements Runnable {
   private static final long SLEEP_TIME = 3000;
   private static final String TEXT = "Sent off of EDT\n";
   private MyTextBox myTextBox;

   public SendTextOffEdt(MyTextBox myTextBox) {
      this.myTextBox = myTextBox;
   }

   @Override
   public void run() {
      while (true) {
         myTextBox.appendTextOffEdt(TEXT);
         try {
            Thread.sleep(SLEEP_TIME);
         } catch (InterruptedException e) {
         }
      }
   }
}

class MyTextBox {
   public static final String REGULAR = "regular";
   public static final String BLUE = "blue";
   public static final String RED_BOLD = "red bold";
   private JTextPane textPane = new JTextPane();
   private JScrollPane scrollPane = new JScrollPane(textPane);
   private String name = "This is your message!! Message  Message "
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!! Message  Message "
         + "This is your message!!\n\n Message \n\n Message \n\n"
         + "This is your message!!\n\n Message \n\n Message \n\n";
   private StyledDocument doc = textPane.getStyledDocument();

   public MyTextBox() {
      addStylesToDocument(doc);
      textPane.setEditable(false);
      textPane.setFocusable(false);
      try {
         doc.insertString(0, name, doc.getStyle("regular"));
      } catch (BadLocationException e) {
         e.printStackTrace();
      }

      scrollPane.setBorder(BorderFactory.createCompoundBorder(
            BorderFactory.createTitledBorder("JTextPane"),
            scrollPane.getBorder()));
   }

   private void addStylesToDocument(StyledDocument doc2) {
      Style def = StyleContext.getDefaultStyleContext().getStyle(
            StyleContext.DEFAULT_STYLE);

      Style regular = doc.addStyle(REGULAR, def);
      StyleConstants.setFontFamily(def, "SansSerif");
      StyleConstants.setFontSize(regular, 16);

      Style s = doc.addStyle(BLUE, regular);
      StyleConstants.setForeground(s, Color.blue);

      s = doc.addStyle(RED_BOLD, regular);
      StyleConstants.setBold(s, true);
      StyleConstants.setForeground(s, Color.red);

   }

   public JScrollPane getMainComponent() {
      return scrollPane;
   }

   public void setText(String text) throws BadLocationException {
      doc.remove(0, doc.getLength());
      doc.insertString(0, text, doc.getStyle(REGULAR));
   }

   public void appendText(String text) throws BadLocationException {
      doc.insertString(doc.getLength(), text, doc.getStyle(REGULAR));
   }

   public void appendTextInBlue(String text) throws BadLocationException {
      doc.insertString(doc.getLength(), text, doc.getStyle(BLUE));
   }

   public void appendTextInRedBold(String text) throws BadLocationException {
      doc.insertString(doc.getLength(), text, doc.getStyle(RED_BOLD));
   }

   public void appendTextOffEdt(final String text) {
      // first make sure that we're in fact off of the EDT
      if (SwingUtilities.isEventDispatchThread()) {
         try {
            appendTextInRedBold(text);
         } catch (BadLocationException e) {
            e.printStackTrace();
         }
      } else {
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               try {
                  appendTextInRedBold(text);
               } catch (BadLocationException e) {
                  e.printStackTrace();
               }
            }
         });
      }
   }
}

至于教程:

于 2013-09-07T23:48:18.353 回答