java JTextArea 中特定文本的 ActionListener?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10462725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:08:54  来源:igfitidea点击:

ActionListener for a specific text inside a JTextArea?

javaswingeventsmouseeventjtextarea

提问by Claudiu C

I have in my app a chat component which has a JTextAreaon it. Now, how can I add an ActionListener-like event for a specific text (like student://xxxx)?

我的应用程序中有一个聊天组件,上面有一个JTextArea。现在,如何为特定文本(如 student://xxxx)添加类似 ActionListener 的事件?

So when I click on that text (student://xxxx) something will happen. Thank you.

因此,当我单击该文本 (student://xxxx) 时,会发生一些事情。谢谢你。

回答by nIcE cOw

Here try this small program, try to click at the start of student://, that will pop up a message Dialog

这里试试这个小程序,尝试点击student://开头的,会弹出一个消息Dialog

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TextAreaExample extends JFrame
{
    private JTextArea tarea =  new JTextArea(10, 10);
    private JTextField tfield = new JTextField(10);

    private void createAndDisplayGUI()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        tarea.setText("Hello there\n");
        tarea.append("Hello student://");
        JScrollPane scroll = new JScrollPane(tarea);

        tfield.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                tarea.append(tfield.getText() + "\n");
            }
        });

        tarea.addMouseListener(new MouseAdapter()
        {
            public void mouseClicked(MouseEvent me)
            {
                int x = me.getX();
                int y = me.getY();
                System.out.println("X : " + x);
                System.out.println("Y : " + y);
                int startOffset = tarea.viewToModel(new Point(x, y));
                System.out.println("Start Offset : " + startOffset);
                String text = tarea.getText();
                int searchLocation = text.indexOf("student://", startOffset);
                System.out.println("Search Location : " + searchLocation);
                if (searchLocation == startOffset)
                    JOptionPane.showMessageDialog(TextAreaExample.this, "BINGO you found me.");
            }
        });

        getContentPane().add(scroll, BorderLayout.CENTER);
        getContentPane().add(tfield, BorderLayout.PAGE_END);
        pack();
        setLocationByPlatform(true);
        setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TextAreaExample().createAndDisplayGUI();
            }
        });
    }
}

回答by Hovercraft Full Of Eels

No, don't even consider this since ActionListeners are for JButtons or anything else derived from AbstractButton but not for JTextComponents (except for JTextFields). Perhaps you want a MouseListener.

不,甚至不要考虑这一点,因为 ActionListeners 适用于 JButtons 或从 AbstractButton 派生的任何其他东西,但不适用于 JTextComponents(JTextFields 除外)。也许你想要一个 MouseListener。

Having said this, perhaps you'll be better off with two text components, a JTextArea to display all responses, including the user's, and right below this in a BorderLayout.SOUTH type of position, a JTextField to allow the user to enter text into the chat. Then give that JTextField an ActionListener (this is legal) so that "enter" will actuate the listener.

话虽如此,也许你会更好地使用两个文本组件,一个 JTextArea 来显示所有响应,包括用户的,在此下方的 BorderLayout.SOUTH 类型的位置,一个 JTextField 允许用户将文本输入到聊天。然后给 JTextField 一个 ActionListener(这是合法的),以便“输​​入”将启动侦听器。

Edit 1
You state:

编辑 1
您声明:

Well I have that jtextfield , the text in it is being sent to the server and server sends the message to all clients which appears in the JTextArea. But my problem is here: I want to popup a window when someone clicks on a student://id text .

好吧,我有那个 jtextfield ,其中的文本被发送到服务器,服务器将消息发送到出现在 JTextArea 中的所有客户端。但我的问题是:当有人点击 student://id 文本时,我想弹出一个窗口。

Yeah, looking at your comments, my vote is for you to display the chats not in a JTextArea but rather in a JList, one with a SelectionListener. You can then respond easily to mouse click events, and will more easily get useful information from the "line" clicked on (if you fill the JList with smart objects). You will need to write a custom cell renderer that allows multiple lines of text to be displayed, probably one that shows a JTextArea, but the tutorial on JLists will get you started on this.

是的,看看你的评论,我的投票是让你不在 JTextArea 中显示聊天,而是在 JList 中显示聊天,一个带有 SelectionListener 的。然后,您可以轻松响应鼠标单击事件,并且可以更轻松地从单击的“行”中获得有用的信息(如果您用智能对象填充 JList)。您将需要编写一个允许显示多行文本的自定义单元格渲染器,可能是一个显示 JTextArea 的文本,但有关 JLists 的教程将帮助您开始这方面的工作。

回答by user unknown

Is hitting ENTER instead of mouse-click ok?

按 ENTER 而不是单击鼠标可以吗?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class StudentID extends JFrame implements ActionListener
{
    private static final String progname = "StudentID 0.1";

    private JTextField student;
    private JTextArea feedback;
    private JButton exit;

    public StudentID ()
    {
        super (progname);
        JPanel mainpanel = new JPanel ();
        mainpanel.setLayout (new BorderLayout ());
        this.getContentPane ().add (mainpanel);

        student = new JTextField ("student://");
        exit = new JButton ("exit");
        student.addActionListener (this);
        exit.addActionListener (this);
        feedback = new JTextArea ();
        mainpanel.add (student, BorderLayout.NORTH);
        mainpanel.add (feedback, BorderLayout.CENTER);
        mainpanel.add (exit, BorderLayout.SOUTH);

        setSize (400, 400);
        setLocation (100, 100);
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setVisible (true);
    }

    public void actionPerformed (final ActionEvent e)
    {
        SwingWorker worker = new SwingWorker () 
        {
            protected String doInBackground () throws InterruptedException 
            {
                String cmd = e.getActionCommand ();
                if (cmd.equals ("exit"))
                {
                    System.exit (0);
                }
                else if (cmd.matches ("student://[0-9]+")) 
                {
                    feedback.setText ("student found: " + cmd.replaceAll ("student://([0-9]+)", ""));
                }
                else
                {
                    feedback.setText ("cmd: " + cmd);
                }
                return "done";
            }
            protected void done () 
            {
                feedback.setText (feedback.getText () + "\ndone");
            }
        };
        worker.execute ();
    }

    public static void main (final String args[])
    {
        Runnable runner = new Runnable () 
        {
            public void run () 
            {
                new StudentID ();
            }
        };
        EventQueue.invokeLater (runner);
    }
}