JLabel закрашивает новый текст поверх старого, после того, как заданный текст вызван - PullRequest
6 голосов
/ 05 января 2011

У меня есть диалоговое окно прогресса, которое содержит 3 JComponents: JLabel, JProgressBar, JButton, которое используется в качестве диалогового окна по умолчанию в разных частях приложения из разных потоков. Поэтому, когда я пытаюсь изменить значение метки, он не очищает фон под ним, он просто закрашивает новый текст поверх старого. Класс-оболочка не переопределяет никакие методы, он просто делегирует вызовы методов содержащимся в нем компонентам.

Вот код:

  public void setNote(String note) {
        this.note = note;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               label.setText(ProgressDialog.this.note);
            }
         });
    }

Фактический результат похож на http://www.daniweb.com/forums/post1073367.html#post1073367 Но это решение не подходило для меня.

Кто-нибудь сталкивался с такой проблемой?

Спасибо.

Это версия класса. Но, как я уже сказал, я не мог заставить его работать неправильно. Надеюсь, это поможет.

    public class Tesssst {

    public static void main(String [] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        ProgressDialog dialog = new ProgressDialog(frame, "Title", "Message");
        dialog.showDialog(true);

    }
}

class ProgressDialog extends JComponent {
    /**
     *
     */
    private JProgressBar progressBar;
    private JLabel label;
    private JFrame parentComponent;
    private String title;
    private String note;
    private boolean canceled;
    private boolean cancelEnabled;
    private JButton btnCancel;
    private JPanel contentPanel;

    public ProgressDialog(JFrame parentComponent, String title, String message) {
        this.parentComponent = parentComponent;
        this.title = title;
        progressBar = new JProgressBar();
        label = new JLabel();
        contentPanel =new JPanel();
        canceled = false;
        cancelEnabled = true;
        setNote(message);
        setOpaque(true);

    }
    public void setNote(String note) {
        this.note = note;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                label.setText(ProgressDialog.this.note);
            }
         });
    }

    public String getNote() {
        return note;
    }

    protected void initDialog() {
        setBorder(new EmptyBorder(6, 6, 6, 6));
        contentPanel = new JPanel();
        contentPanel.setOpaque(true);
        setLayout(new BorderLayout());
        add(contentPanel);
        btnCancel = new JButton("Cancel");
        btnCancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                label.setText("ololo");
            }

        });

        contentPanel.setLayout(new GridBagLayout());
        {
        GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.NONE;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.insets = new Insets(2, 0, 0, 0);
            label.setOpaque(true);
            contentPanel.add(label, gbc);
        } // label

        {
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.anchor = GridBagConstraints.NORTH;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(4, 0, 4, 0);
            contentPanel.add(progressBar, gbc);
        } // progressBar

        {
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 2;
            gbc.anchor = GridBagConstraints.NORTH;
            gbc.fill = GridBagConstraints.NONE;
            gbc.insets = new Insets(4, 0, 4, 0);
            contentPanel.add(btnCancel, gbc);
            btnCancel.setEnabled(cancelEnabled);
        } // cancel*/
    } // funciton

    public boolean isCanceled() {
        return canceled;
    }

    public void showDialog() {
        showDialog(false);
    }

    public void showDialog(boolean modal) {
        JDialog dialog = new JDialog(parentComponent, true);
        initDialog();
        dialog.getContentPane().add(contentPanel);
        dialog.setSize(400,400);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        if (modal) {
            dialog.setAlwaysOnTop(true);
        }
        dialog.setVisible(true);
        dialog.toFront();
    }

    public void cancel() {
        canceled = true;
    }

}

Ответы [ 6 ]

4 голосов
/ 05 января 2011

Попробуйте setOpaque(true) на ярлыке, это должно привести к очистке фона.

2 голосов
/ 06 января 2011

Проблема была с непрозрачностью.В нашем внешнем виде свойство Panel.background было установлено на new Color(135, 15, 19, 0).Так что все панели по умолчанию были непрозрачными.Метка называлась repaint() method, и поскольку все родительские панели были непрозрачными, обновление фона не было выполнено.

Спасибо всем за ответы.

2 голосов
/ 05 января 2011

Попробуйте расширить JPanel вместо JComponent.

У JComponent нет кода для рисования фона.Поэтому создание непрозрачного компонента ничего не делает для удаления старого текста.Держите метку непрозрачной и используйте непрозрачную JPanel в качестве контейнера вашего компонента.

Возможно, вы где-то используете фоны с альфа-значением.Если это так, вы можете проверить Background With Transparency на некоторые проблемы, с которыми вы можете столкнуться.

В противном случае только вы можете сравнить свой рабочий код с нерабочим кодом, чтобы увидеть, что отличается

2 голосов
/ 05 января 2011

попробуйте, возможно, repaint() на соответствующем компоненте после установки текста.

1 голос
/ 05 января 2011

Ответ от camickr - правильный путь; однако в вашем тесте однозначно не правильно использовать нить качания.

Я подозреваю, что это также может иметь отношение к диалогу. Диалоги обычно блокируют SWMET при вызове showDialog (); таким образом, второй поток событий обычно создается в showDialog (). Здесь вы не вызываете showDialog () из SWMET, который вы вызываете из основного - возможно, вы видите странные эффекты этого.

public static void main(String args[]) throws Exception {
 SwingUtils.invokeLater(new Runnable() {
 public void run() {
   ProgressDialog dialog = new ProgressDialog(frame, "Title", "Message");
   dialog.showDialog(true);
 }
 });
}
0 голосов
/ 11 декабря 2015

нужно поставить super.paintComponent(g);

...