代码之家  ›  专栏  ›  技术社区  ›  Radim Burget

JTextPane-获取组件值

  •  1
  • Radim Burget  · 技术社区  · 8 年前

    我有JTextPane,其中插入了2个JLabel。如果单击了任何标签,它们会将内容从AAA更改为单击。

    此代码遍历JTextPane中的元素:

            for(int i = 0; i < tp.getDocument().getLength(); i++) {
                System.out.println(((StyledDocument) tp.getDocument()).getCharacterElement(i));
            }
    

    如何访问标签以将“点击”“AAAA”打印到标准输出?

    enter image description here

    package texteditor;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
    import javax.swing.JPopupMenu;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.border.BevelBorder;
    import javax.swing.border.TitledBorder;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.StyledDocument;
    import javax.swing.JButton;
    
    public class JTextPaneExample extends JPanel {
    
        private JTextPane tp;
    
        public JTextPaneExample() {
            setLayout(new BorderLayout(0, 0));
    
            JPanel panel = new JPanel();
            panel.setBorder(new TitledBorder(null, "Text Content", TitledBorder.LEADING, TitledBorder.TOP, null, null));
            add(panel, BorderLayout.CENTER);
            panel.setLayout(new BorderLayout(0, 0));
    
            JScrollPane scrollPane = new JScrollPane();
            panel.add(scrollPane, BorderLayout.CENTER);
    
            tp = new JTextPane();
            tp.setEditable(false);
            scrollPane.setViewportView(tp);
    
            JLabel lbl = new JLabel("AAAA ");
            lbl.setOpaque(true);
            lbl.setBorder(BorderFactory.createLineBorder(Color.black, 1));
            lbl.addMouseListener(new LabelAdapter2(lbl));
            tp.insertComponent(lbl);
    
            lbl = new JLabel("BBBB ");
            lbl.setOpaque(true);
            lbl.setBorder(BorderFactory.createLineBorder(Color.black, 1));
            lbl.addMouseListener(new LabelAdapter2(lbl));
            tp.insertComponent(lbl);
    
            JButton btnNewButton = new JButton("Write content");
            btnNewButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    iterateOverContent(tp);
                }
            });
            panel.add(btnNewButton, BorderLayout.SOUTH);
        }
    
        private void iterateOverContent(JTextPane tp2) {
                for(int i = 0; i < tp.getDocument().getLength(); i++) {
                    System.out.println(((StyledDocument) tp.getDocument()).getCharacterElement(i));
                }
        }
    
        private class LabelAdapter2 extends MouseAdapter {
            private JLabel lblNewLabel;
    
            public LabelAdapter2(JLabel lbl) {
                this.lblNewLabel = lbl;
            }
    
    
            public void mouseClicked(MouseEvent evt) {
                lblNewLabel.setText("clicked");
            }
        }
    
        public static void main(String[] args) {
            JFrame frame = new JFrame("GoBoard");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new JTextPaneExample());
            frame.setPreferredSize(new Dimension(400, 400));
            frame.pack();
            frame.setVisible(true);
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Dave T.    8 年前

    我仔细研究了你的问题,找到了解决方案:

    只需将迭代TextPane元素的方法替换为:

    private void iterateOverContent(JTextPane tp2) {
            for(int i = 0; i < tp.getDocument().getLength(); i++) {
                Element elem = ((StyledDocument) tp.getDocument()).getCharacterElement(i);
                AttributeSet as = elem.getAttributes();
                if (as.containsAttribute(AbstractDocument.ElementNameAttribute, StyleConstants.ComponentElementName)) {
                    if(StyleConstants.getComponent(as) instanceof JLabel) {
                        JLabel myLabel = (JLabel)StyleConstants.getComponent(as);
                        System.out.println(myLabel.getText());
                    }
                }
                System.out.println(((StyledDocument) tp.getDocument()).getCharacterElement(i));
            }
    }
    

    如您所见,我首先将元素保存到一个新变量中,然后读取所有属性(是的,代码可能会更短,但这样更清晰-我希望:-) 之后,我们检查属性是否表示该元素是组件。

    然后是重要的部分:我们可以通过StyleConstants从属性集中获取Component。getComponent方法。

    最后只是一些理智的检查,看看我们是否真的可以将它键入JLabel。

    顺致敬意, 大卫