JLabel рисует новый текст поверх старого, после вызова set text
у меня есть диалоговое окно прогресса, которое содержит 3 компонента: 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 Но это решение не подходило мне.
кто-нибудь сталкивался с такой проблемой?
спасибо.
это cuted версия класса. Но, как я уже сказал, Я не мог заставить его работать неправильно. Надеюсь, это поможет.
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 ответов
попробовать setOpaque(true)
на этикетке это должно привести к очистке фона.
попробуйте расширить JPanel вместо JComponent.
JComponent не имеет кода для рисования фона. Таким образом, непрозрачный компонент не делает ничего, чтобы стереть старый текст. Держите метку непрозрачной и используйте непрозрачную JPanel в качестве контейнера вашего компонента.
возможно, вы используете фоны с Альфа-значением где-то. Если это так, вы можете проверить Фон С Прозрачностью для некоторых проблем, которые могут столкновение.
в противном случае только вы можете сравнивать ваш код с неработающим кодом, чтобы увидеть, что изменилось.
проблема с прозрачностью. В нашей панели "внешний вид по умолчанию".свойство "background" было установлено в new Color(135, 15, 19, 0)
. Таким образом, все панели по умолчанию были непрозрачными. Этикетка называлась repaint()
метод и поскольку все родительские панели были непрозрачными, фоновое обновление не выполнялось.
спасибо всем за ответы.
ответ от camickr-это правильный способ продолжить; однако одна вещь, явно неправильная с вашим тестом, - это использование swing thread.
Я подозреваю, что это также может иметь какое-то отношение к тому, что это диалог. Диалоговые окна обычно блокируют SWMET в вызове showDialog (); таким образом, второй поток событий обычно создается в showDialog (). Здесь вы не вызываете showDialog() из SWMET, который вы вызываете из main - возможно, вы видите некоторые странные эффекты что.
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);
}
});
}