Java 如何从另一个类刷新JTextPane
我知道这个问题已经被问过好几次了。我试图从另一个类刷新我的JTextPane,当我从我的主类刷新它时,它可以工作,但任何其他类都不能。我听说您需要使用线程来实现它,但我还没有看到有人真正实现它。我在下面尽可能简单地提供了我的代码。有三节课。谢谢 下面是它的输出:Java 如何从另一个类刷新JTextPane,java,multithreading,swing,jscrollpane,jtextpane,Java,Multithreading,Swing,Jscrollpane,Jtextpane,我知道这个问题已经被问过好几次了。我试图从另一个类刷新我的JTextPane,当我从我的主类刷新它时,它可以工作,但任何其他类都不能。我听说您需要使用线程来实现它,但我还没有看到有人真正实现它。我在下面尽可能简单地提供了我的代码。有三节课。谢谢 下面是它的输出: //我创建了一个新类来演示我在更改文档时要做的事情 我正在尝试刷新另一个类的JTextPane 至于更新另一个类中的字段,您应该为保存该字段的类提供一个公共方法,其他类可以调用该方法来更改该字段的状态。例如,如果您希望允许另一个类
//我创建了一个新类来演示我在更改文档时要做的事情
我正在尝试刷新另一个类的JTextPane 至于更新另一个类中的字段,您应该为保存该字段的类提供一个公共方法,其他类可以调用该方法来更改该字段的状态。例如,如果您希望允许另一个类更改
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,但我并不经常使用它们
当我在我的主课上做这件事的时候,它是有效的,但是其他的课都不行。我听说您需要使用线程来实现它,但我还没有看到有人真正实现它。我在下面尽可能简单地提供了我的代码
如果您在EDT(事件调度线程)之外对Swing GUI进行更改,则会出现线程问题,EDT是主Swing线程。如果出现这种情况,那么您应该将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线程,请阅读
编辑4
一个示例:
编辑5
要从另一个线程发送,正如我在其他地方提到的,只需将代码包装成可运行的,并通过
SwingUtilities.invokeLater(myRunnable)
将其排入EDT队列
例如,我可以给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();
}
}
});
}
}
}
至于教程:
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,但我并不经常使用它们
当我在我的主课上做这件事的时候,它是有效的,但是其他的课都不行。我听说您需要使用线程来实现它,但我还没有看到有人真正实现它。我在下面尽可能简单地提供了我的代码
如果您在EDT(事件调度线程)之外对Swing GUI进行更改,则会出现线程问题,EDT是主Swing线程。如果出现这种情况,那么您应该将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线程,请阅读
编辑4
一个示例:
编辑5
要从另一个线程发送,正如我在其他地方提到的,只需将代码包装成可运行的,并通过
SwingUtilities.invokeLater(myRunnable)
将其排入EDT队列
例如,我可以给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();
}
}
});
}
}
}
至于教程:
文本框
类中有一个JTextPane
声明,它是第一行。@JoshM:没有看到,但现在看到了。更新答案。@HovercraftFullOfEels“如果您正在进行