Java Текст Swing JTextPane / html не учитывает отключенный атрибут - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь отобразить простую страницу HTML в JTextPane. На странице есть элементы ввода / радио, но их нужно отключить. Тем не менее, когда страница отображается, флажок и переключатели все еще включены. Я не хочу, чтобы пользователь мог щелкнуть и изменить свое состояние. Это ошибка или я делаю что-то не так. Пожалуйста помоги. Вот пример кода:

import javax.swing.*;
public class JEPTest {
    public static void main(String[] args) throws Exception{
        String data = "<html>\n" +
"\n" +
"<body>\n" +
"<input type='radio' disabled>\n" +
"\n" +
"</body>\n" +
"</html>";

    final JEditorPane textPane = new JEditorPane();
        textPane.setContentType("text/html");
        textPane.setEnabled(false);
        JScrollPane paneScrollPane = new JScrollPane(textPane);
        paneScrollPane.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        paneScrollPane.setHorizontalScrollBarPolicy(
                        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        //paneScrollPane.setPreferredSize(new Dimension(250, 155));
        paneScrollPane.setMinimumSize(new Dimension(100, 100));        


    JButton jb = new JButton("set");
    jb.addActionListener
        (
        new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
        textPane.setText(data);

        }
    }
        );

    JFrame jf = new JFrame();
    jf.setSize(800, 600);       

    jf.getContentPane().add(textPane, BorderLayout.CENTER);
    jf.getContentPane().add(jb, BorderLayout.SOUTH);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);

    }
}

1 Ответ

2 голосов
/ 25 февраля 2020

Swing использует старый механизм рендеринга HTML, который поддерживает только HTML 3.2. Спецификация HTML 3.2 показывает, что элемент <input> не допускал атрибут disabled во время этой версии. Определены следующие атрибуты:

<!ATTLIST INPUT
        type %InputType TEXT     -- what kind of widget is needed --
        name  CDATA #IMPLIED     -- required for all but submit and reset --
        value CDATA #IMPLIED     -- required for radio and checkboxes --
        checked (checked) #IMPLIED -- for radio buttons and check boxes --
        size CDATA  #IMPLIED     -- specific to each type of field --
        maxlength NUMBER #IMPLIED
        src   %URL  #IMPLIED     -- for fields with background images --
        align %IAlign #IMPLIED   -- vertical or horizontal alignment --
        >

Лучший обходной путь - избегать использования JEditorPane и просто создавать экземпляр JCheckBox в JPanel.

В качестве альтернативы вы можете встроить любой визуальный компонент Java, включая всех потомков JComponent, в документ HTML JEditorPane, используя элемент <object>. Это описано в документации javax.swing.text. html .ObjectView .

Эту возможность можно использовать для непосредственного встраивания JRadioButton. Однако, только свойства String могут быть установлены таким образом, поэтому вам нужно будет создать свой собственный подкласс JRadioButton и добавить свойство String, которое обернет свойство enabled:

public class JEPTest {
    public static class StringPropRadioButton
    extends JRadioButton {
        private static final long serialVersionUID = 1;

        public String getEnabledAsString() {
            return String.valueOf(isEnabled());
        }

        public void setEnabledAsString(String enabled) {
            setEnabled(Boolean.parseBoolean(enabled));
        }
    }

    public static void main(String[] args) throws Exception{
        String data = "<html>\n" +
        "\n" +
        "<body>\n" +
        "<input type='radio' disabled>\n" +
        "\n" +
        "<p>" +
            "<object classid='JEPTest$StringPropRadioButton' id='option1'>" +
            "    <param name='text' value='Option 1'>" +
            "    <param name='enabledAsString' value='false'>" +
            "</object>" +
        "</body>\n" +
        "</html>";
...