Как установить ширину JTextPane и использовать автоматическую высоту, связанную с текстом? - PullRequest
0 голосов
/ 02 февраля 2019

Я уже нашел эту тему, но, к сожалению, она не работает.Что я пытаюсь сделать: я разрабатываю небольшой инструмент с помощью Java Swing.Для некоторых функций в моем инструменте я хочу отобразить собственную подсказку подсказка , чтобы дать некоторую информацию.

Вот пример: Краткий текст

Это мои настройки:

JDialog
+-jPanel (transparent container) 
| +-jPanel (dark background for my text pane)
|   +-jTextPane
+-jLabel (holds the arrow image)

Если пользователь наведет курсор на маленький i , он сможет увидеть информационное окно.Все идет нормально.Я создал класс для этого информационного блока, установил только текст и сделал его видимым при наведении мыши и сделал его невидимым при выходе из мыши.

Это работает как шарм.Если я устанавливаю другой текст (на другом i для отображения другой информации, я использую только мой публичный setText метод и снова устанавливаю его видимым. См. Следующее изображение: Более длинный текст, см.автоматическая высота

Изображение имеет ту же ширину, но другую (авто) высоту. А теперь моя проблема : я хочу иметь возможность определить другую ширину (отличную от набора по умолчанию)1) чтобы избежать слишком большого информационного блока, если текст длинный, но если я это сделаю, мой информационный блок не будет работать, см .:

Длинный текст с измененной шириной, ошибка

Это мой код (я удалил автоматически сгенерированный код Netbeans):

import java.awt.BorderLayout;
import java.awt.Color;

public class MyToolTip extends javax.swing.JDialog {

    public MyToolTip(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        makeMeTransparent();
    }

    public void setText (String text, Integer width) {
        String s;

        s  = "<html><body><p style=\"margin-top: 0; color: #ffffff; font-family:Tahoma; font-size:11px\">";
        s += text;
        s += "</p></body></html>";

        jTextPane_Tip.setText(s);

        if(width == 0) {
            width = 250;
        }

        setWidth(width);
        repaint();
        pack();
    }

    private void setWidth (Integer width) {        
        jTextPane_Tip.setSize(width, Integer.MAX_VALUE);
        jTextPane_Tip.setSize(width, jTextPane_Tip.getPreferredSize().height);
    }

    /* Netbeans auto generated code (hidden) */

    private void makeMeTransparent() {
        setBackground(new Color(0, 255, 0, 0));
        jPanel_Main.setBackground(new Color(0, 255, 0, 0));
        setContentPane(new MyContentPane());
        getContentPane().setBackground(Color.BLACK);
        setLayout(new BorderLayout());
        getContentPane().add(jPanel_Main);
    }
}

Как установить ширину JTextPane и использовать автоматическую высоту, связанную с текстом?

Редактировать:

Вот мой минимальный пример:

Файл MyTT.java:

package mytt;

public class MyTT {

    public static void main(String[] args) {
        NewJFrame frame = new NewJFrame();
        frame.setVisible(true);
    }
}

Файл NewJFrame.java:

package mytt;

public class NewJFrame extends javax.swing.JFrame {

    private final MyToolTip tt;

    public NewJFrame() {
        initComponents();
        tt = new MyToolTip(this, false);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Hover me for Tool-Tip (default width)");
        jLabel1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jLabel1MouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                jLabel1MouseExited(evt);
            }
        });

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel2.setText("Hover me for Tool-Tip (user defined width)");
        jLabel2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                jLabel2MouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                jLabel2MouseExited(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addGap(108, 108, 108)
                .addComponent(jLabel2)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void jLabel1MouseEntered(java.awt.event.MouseEvent evt) {                                     
        int x = jLabel1.getLocationOnScreen().x + jLabel1.getWidth() + 4;
        int y = jLabel1.getLocationOnScreen().y;   

        tt.setText("This is a simple example text. The width isn't changed and the height will be automatically set.",0);
        tt.setLocation(x,y);
        tt.setVisible(true);
    }                                    

    private void jLabel2MouseEntered(java.awt.event.MouseEvent evt) {                                     
        int x = jLabel2.getLocationOnScreen().x + jLabel1.getWidth() + 4;
        int y = jLabel2.getLocationOnScreen().y;   

        tt.setText("This is a simple example text. I set the width to a user defined value. This will crash the box somehow",400);
        tt.setLocation(x,y);
        tt.setVisible(true);
    }                                    

    private void jLabel1MouseExited(java.awt.event.MouseEvent evt) {                                    
        tt.setVisible(false);
    }                                   

    private void jLabel2MouseExited(java.awt.event.MouseEvent evt) {                                    
        tt.setVisible(false);
    }                                   

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(() -> {
            new NewJFrame().setVisible(true);
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration                   
}

Файл MyToolTip.java:

package mytt;

public class MyToolTip extends javax.swing.JDialog {

    public MyToolTip(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    public void setText (String text, Integer width) {     
        jTextPane_Tip.setText(text);

        // if the user doesn't defined a width, take the default width
        if(width == 0) width = 150;

        // resize the box
        setWidth(width);
    }

    private void setWidth (Integer width) {        
        jTextPane_Tip.setSize(width, Integer.MAX_VALUE);
        jTextPane_Tip.setSize(width, jTextPane_Tip.getPreferredSize().height);
        pack();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel_Main = new javax.swing.JPanel();
        jPanel_Background = new javax.swing.JPanel();
        jTextPane_Tip = new javax.swing.JTextPane();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Variable Platzhalter");
        setFocusableWindowState(false);
        setUndecorated(true);
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });

        jPanel_Background.setBackground(new java.awt.Color(29, 29, 29));

        jTextPane_Tip.setEditable(false);
        jTextPane_Tip.setBackground(new java.awt.Color(29, 29, 29));
        jTextPane_Tip.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jTextPane_Tip.setForeground(new java.awt.Color(255, 255, 255));
        jTextPane_Tip.setText("");

        javax.swing.GroupLayout jPanel_BackgroundLayout = new javax.swing.GroupLayout(jPanel_Background);
        jPanel_Background.setLayout(jPanel_BackgroundLayout);
        jPanel_BackgroundLayout.setHorizontalGroup(
            jPanel_BackgroundLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel_BackgroundLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextPane_Tip, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel_BackgroundLayout.setVerticalGroup(
            jPanel_BackgroundLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel_BackgroundLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextPane_Tip)
                .addContainerGap())
        );

        javax.swing.GroupLayout jPanel_MainLayout = new javax.swing.GroupLayout(jPanel_Main);
        jPanel_Main.setLayout(jPanel_MainLayout);
        jPanel_MainLayout.setHorizontalGroup(
            jPanel_MainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel_MainLayout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addComponent(jPanel_Background, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel_MainLayout.setVerticalGroup(
            jPanel_MainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel_Background, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        getContentPane().add(jPanel_Main, java.awt.BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>                        

    private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
        this.dispose();
    }                               

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MyToolTip.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        /* Create and display the dialog */
        java.awt.EventQueue.invokeLater(() -> {
            MyToolTip dialog = new MyToolTip(new javax.swing.JFrame(), true);
            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JPanel jPanel_Background;
    private javax.swing.JPanel jPanel_Main;
    private javax.swing.JTextPane jTextPane_Tip;
    // End of variables declaration                   
}

Результат минимального примера: Хорошо, пользовательская ширина не указана Ошибка, пользовательская ширина

Edit 2:

Хорошо, вторая попытка: я написал минимальный собственный пример (без автоматически сгенерированного кода из Netbeans).Я надеюсь, что это достаточно мало.И теперь хорошие новости: программа работает точно так, как я ожидал (также от моего реального проекта).

MCVE.java: package mcve;

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MCVE {

    public static void main(String[] args) {

        MyToolTip tt = new MyToolTip(null,false);
        JFrame f = new JFrame();
        JLabel l1 = new JLabel("Please hover me (default size)");
        JLabel l2 = new JLabel("Please hover me (defined size)");
        JPanel p = new JPanel();

        l1.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseEntered(MouseEvent evt) {
                int x = l1.getLocationOnScreen().x + l1.getWidth() + 4;
                int y = l1.getLocationOnScreen().y;   

                tt.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr",200);
                tt.setLocation(x,y);
                tt.setVisible(true);
            }

            @Override
            public void mouseExited(MouseEvent evt) {
                tt.setVisible(false);
            }
        });

        l2.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseEntered(MouseEvent evt) {
                int x = l2.getLocationOnScreen().x + l2.getWidth() + 4;
                int y = l2.getLocationOnScreen().y;   

                tt.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",300);
                tt.setLocation(x,y);
                tt.setVisible(true);
            }

            @Override
            public void mouseExited(MouseEvent evt) {
                tt.setVisible(false);
            }
        });

        p.add(l1);
        p.add(l2);
        p.setPreferredSize(new Dimension(200,50));

        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);       
        f.setVisible(true);
    }
}

MyToolTip.java:

package mcve;

import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JTextPane;

public class MyToolTip extends javax.swing.JDialog { 
    private JPanel p;
    private JTextPane tp;

    public MyToolTip(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComp();
    }

    public void setText(String text, Integer width) {
        tp.setText(text);

        if(width > 0) {
            tp.setSize(width, Integer.MAX_VALUE);
            tp.setPreferredSize(new Dimension(width, tp.getPreferredSize().height));
        }

        pack();
    }

    private void initComp () {
        p = new JPanel();
        tp = new JTextPane();
        p.add(tp);
        add(p);
    }
}

Вопрос теперь: почему это работает во втором минимальном примере, а не в моем проекте: - (

1 Ответ

0 голосов
/ 02 февраля 2019

В setWidth(Integer) методе в MyToolTip классе вы вызываете jTextPane_Tip.setSize() дважды.Когда я убрал первый звонок

jTextPane_Tip.setSize(width, Integer.MAX_VALUE);

, это сработало.

...