Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a checkbox with an hyperlink

Question :

I'm try to create an check-box in Java that contains in the text an hyper-link.

But, I couldn't make the link clickable, and only the link, not the whole text.

enter image description here

Here 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();
    }
}

The frame1 show a simple check-box and the whole text is clickable and check/uncheck the box. That's why I made the frame2, made by the composition of a check box and and a JLabel. It work well, but it's all the text that is clickable.

Are there any way to have only the link clickable ?

Thanks

Luffy


[EDIT] Reponse :

Thanks to @camickr to give me a piece of response.

Here the solution, that is not so easy to do 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 to understand :

  • I have use the JtextPane in place of the JEditorPane because the text doesn't wrap in the text editor and I could do it with my html tag.
  • I have modified the text provided to add the bold and underline tags <b><u> and also I have change the color to the hyperlink to be as a normal link. In other case, you will have the link, but it will have the same color of your text.
  • Pay attention at the HyperlinkListener that generate an event each time your mouse is over the link, that why I have filtered the event with HyperlinkEvent.EventType.ACTIVATED that correspond to a 'click'
  • Chang the font size/style/color to the whole text it's really tricky, you need to use my technics, the methods setFont doesn't work here

Enjoy :)


[EDIT2] Something to know :

  • In the case you are using the 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 are a bug and you will have a white background. So you need to fix it by adding this piece of code instead of a 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 a JEditorPane but change the line

    defaults.put("EditorPane[Enabled].backgroundPainter", bgColor);
like image 400
MonkeyJLuffy Avatar asked Dec 14 '15 15:12

MonkeyJLuffy


People also ask

How do I make a clickable checkbox in HTML?

The <input type="checkbox"> defines a checkbox. The checkbox is shown as a square box that is ticked (checked) when activated.

Should checkbox label be clickable?

This allows users to activate the element by clicking the label. It doesn't take much to improve the user experience when all you have to do is add a short line of code. Making your checkbox labels clickable can not only do wonders for motor-impaired users but every user on your site.


1 Answers

The only way I know how to make a hyperlink clickable in the base JDK is to use a JEditorPane.

So you could create a JPanel with two components:

  1. a JCheckBox (with no text)
  2. a JEditorPane with your hyperlink

You can easily customize the JEditorPane to be transparent and without a Border so it looks like the two components are a single component.

like image 173
camickr Avatar answered Sep 25 '22 18:09

camickr