Question:
I am trying to create a checkbox in Java that contains a hyperlink in the text.
But I could not make the link clickable and only the link, not the entire text.

Here is my sample code:
public class TestClickLinkInCheckBox implements MouseListener { private JFrame frame1; private JFrame frame2; private String linkedText = "I have checked the data set I have selected, and agree to sign it following <a href=\"http://www.google.com\">the conditions of use of the service, defined in the policies of signature and certification</a> that I attest having read."; private JLabel label; public TestClickLinkInCheckBox() { justCheckBox(); checkBoxWithLabel(); } private void justCheckBox() throws HeadlessException { frame1 = new JFrame(); JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50)); JCheckBox checkBox = new JCheckBox(prettyText(linkedText, 300, "left")); panel.add(checkBox); frame1.add(panel); } private void checkBoxWithLabel() { frame2 = new JFrame(); JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50)); JCheckBox checkBox = new JCheckBox(); panel.add(checkBox); label = new JLabel(prettyText(linkedText, 300, "left")); label.addMouseListener(this); panel.add(label); frame2.add(panel); } private void display() { frame1.setVisible(true); frame1.pack(); frame2.setVisible(true); frame2.pack(); } public static String prettyText(String badText, int length, String textAlign) { return "<html><body width='" + String.valueOf(length) + "px'><div style=\"text-align: " + textAlign + ";\">"+ badText.replace("|||", "<br>") + "</html>"; } @Override public void mouseClicked(MouseEvent e) { if (e.getSource() == label) { JOptionPane.showConfirmDialog(frame2, "Clicked"); } } @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} public static void main(String[] args) { TestClickLinkInCheckBox test = new TestClickLinkInCheckBox(); test.display(); } }
frame1 shows a simple checkbox, and all the text can be clicked and checked / unchecked. This is why I made frame2 made by the checkbox and frame2 composition. It works well, but this is all the text that can be clicked.
Can I use only a link?
thanks
Luffy
[EDIT] Failure:
Thanks @camickr for giving me an answer.
Here is a solution that is not so easy to make at the end:
public class TestClickLinkInCheckBox implements HyperlinkListener { private JFrame frame; private String linkedText = "I have checked the data set I have selected, and agree to sign it following <b><u><a href=\"http://www.google.com\" style=\"color: #0000ff\">the conditions of use of the service, defined in the policies of signature and certification</a></u></b> that I attest having read."; private JTextPane textPane; public static void main(String[] args) { TestClickLinkInCheckBox test = new TestClickLinkInCheckBox(); test.display(); } public TestClickLinkInCheckBox() { checkboxWithJEditorPanel(); } private void checkboxWithJEditorPanel() { frame = new JFrame(); JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50)); JCheckBox checkBox = new JCheckBox(); panel.add(checkBox); textPane = new JTextPane(); textPane.setContentType("text/html"); textPane.setOpaque(false); textPane.setDocument(new HTMLDocument()); textPane.setText(prettyText(linkedText, 300, "left")); textPane.setEditable(false); textPane.addHyperlinkListener(this); setFontSize(16); panel.add(textPane); frame.add(panel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } private void setFontSize(int size) { MutableAttributeSet attrs = textPane.getInputAttributes(); StyleConstants.setFontSize(attrs, size); StyledDocument document = textPane.getStyledDocument(); document.setCharacterAttributes(0, document.getLength() + 1, attrs, false); } private void display() { frame.setVisible(true); frame.pack(); } public static String prettyText(String badText, int length, String textAlign) { return "<html><body width='" + String.valueOf(length) + "px'><div style=\"text-align: " + textAlign + ";\">"+ badText.replace("|||", "<br>") + "</html>"; } @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { System.out.println(e.getURL()); } } }
Some explanations:
- I use JtextPane instead of JEditorPane, because the text is not wrapped in a text editor, and I could do it with my html tag.
- I changed the text provided to add bold and underline
<b><u> tags, and also changed the color of the hyperlink as a regular link. Otherwise, you will have a link, but it will have the same color as your text. - Pay attention to the
HyperlinkListener , which generate an event every time your mouse clicks a link, so I filtered the event using HyperlinkEvent.EventType.ACTIVATED , which correspond to 'click' - Chang the font size / style / color for all the text is very difficult, you need to use my technique,
setFont methods do not work here.
Enjoy :)
[EDIT2] Something to know:
If you are using Nimbus Look&Feel :
try { for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (Exception e) { e.printStackTrace(); }
There is a mistake and you will have a white background. Therefore, you need to fix this by adding this piece of code instead of the setBackground() method:
Color bgColor = panel.getBackground(); UIDefaults defaults = new UIDefaults(); defaults.put("TextPane[Enabled].backgroundPainter", bgColor); textPane.putClientProperty("Nimbus.Overrides", defaults); textPane.putClientProperty("Nimbus.Overrides.InheritDefaults", true); textPane.setBackground(bgColor);
Same for JEditorPane, but change the line
defaults.put("EditorPane[Enabled].backgroundPainter", bgColor);