How to disable the automatic HTML support of JLabel?

前端 未结 3 592
北海茫月
北海茫月 2021-01-02 13:09

A Swing JLabel automatically interprets any text as HTML content, if it starts with . If the content of this HTML is an image with invalid URL this will cause th

相关标签:
3条回答
  • 2021-01-02 13:25

    Hanging is probably the least unpleasant behavior. This is why Data Validation is so very important. Just do not allow the users to enter something like that.

    0 讨论(0)
  • 2021-01-02 13:31

    There is a way if you create your own look and feel.
    I'm not sure how well this performs is this, but it works. Lets assume you will extend the "Classic Windows" L&F.You need at leas 2 classes One is the Look&Feel itself, lets call it WindowsClassicLookAndFeelExt. You only need to override method initClassDefaults.

    package testSwing;
    
    import javax.swing.UIDefaults;
    import com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel;
    
    public class WindowsClassicLookAndFeelExt extends WindowsClassicLookAndFeel    {
        @Override protected void initClassDefaults(UIDefaults table){
            super.initClassDefaults(table);
            Object[] uiDefaults = { "LabelUI", WindowsLabelExtUI.class.getCanonicalName()};
            table.putDefaults(uiDefaults);
        }
    }
    

    You also need a WindowsLabelExtUI class to manage all JLabels and set the property:

    package testSwing;
    import javax.swing.JComponent;
    import javax.swing.plaf.ComponentUI;
    import com.sun.java.swing.plaf.windows.WindowsLabelUI;
    
    public class WindowsLabelExtUI extends WindowsLabelUI{
        static WindowsLabelExtUI singleton = new WindowsLabelExtUI();
    
        public static ComponentUI createUI(JComponent c){
            c.putClientProperty("html.disable", Boolean.TRUE);    
            return singleton;
        }
    }
    

    And finally a test class when you set the theme as WindowsClassicLookAndFeelExt

    package testSwing;
    
    import java.awt.FlowLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JScrollPane;
    import javax.swing.UIManager;
    
    
    public class Main{
        public static void main(String[] args){
            try{                UIManager.setLookAndFeel(WindowsClassicLookAndFeelExt.class.getCanonicalName());
            }catch (Exception e){
                e.printStackTrace();
            }
    
            JFrame frame = new JFrame("JList Test");
            frame.setLayout(new FlowLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            String[] selections = {"<html><img src='http:\\\\invalid\\url'>", "<html><H1>Hello</h1></html>", "orange", "dark blue"};
    
            JList list = new JList(selections);
    
            list.setSelectedIndex(1);
            System.out.println(list.getSelectedValue());
    
            JLabel jLabel = new JLabel("<html><h2>standard Label</h2></html>");
            frame.add(new JScrollPane(list));
            frame.add(jLabel);
            frame.pack();
    
            frame.setVisible(true);
        }
    }
    

    And you will see something like

    alt text

    0 讨论(0)
  • 2021-01-02 13:40

    For a simple JLabel, you can call the JComponent method

    myLabel.putClientProperty("html.disable", Boolean.TRUE);
    

    on the label where you want to disable HTML rendering.

    Reference: Impossible to disable HTML Rendering in a JLabel


    For something like a JTable, JTree, or JList you'll need to create a custom cell renderer that sets this property. Here's an example (modified from this example) that creates a custom cell renderer for a JList.

    import java.awt.Component;
    import java.awt.FlowLayout;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JScrollPane;
    import javax.swing.ListCellRenderer;
    
    public class JListTest {
        public static void main(String[] args) {
            JFrame.setDefaultLookAndFeelDecorated(true);
            JFrame frame = new JFrame("JList Test");
            frame.setLayout(new FlowLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            String[] selections = { "<html><img src='http:\\\\invalid\\url'>",
                    "red", "orange", "dark blue" };
            JList list = new JList(selections);
    
            // set the list cell renderer to the custom class defined below
            list.setCellRenderer(new MyCellRenderer());
    
            list.setSelectedIndex(1);
            System.out.println(list.getSelectedValue());
            frame.add(new JScrollPane(list));
            frame.pack();
    
            frame.setVisible(true);
        }
    }
    
    
    class MyCellRenderer extends JLabel implements ListCellRenderer {
        public MyCellRenderer() {
            setOpaque(true);
            putClientProperty("html.disable", Boolean.TRUE);
        }
    
        public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus)
        {
            setText(value.toString());
            return this;
        }
    }
    

    I used the example code from the ListCellRenderer documentation as a starting point for the custom list cell renderer.

    When I run the example, you can see that the HTML in the first list entry is rendered instead of being interpreted.

    JList Custom Renderer

    0 讨论(0)
提交回复
热议问题