Kilka błędów:
1. Korzystasz bezpośrednio z AWT zamiast ze Swinga.
2. Odpalasz kod odpowiedzialny za UI w głównym wątku programu czego nie powinno się robić. Google: Java EventDispatchThread, SwingUtilitiles.invokeLater().
3. Jeżeli nadpisujesz jakąś metodę z interfejsu Swinga czy AWT powinieneś niemal zawsze wywołać tę samą metodę z klasy nadrzędnej (super.nazwaMetody()).
4. Jeżeli nadpisujesz jakąś metodę
zawsze dodawaj adnotację @Override - uchroni Cię ona przed głupimi błędami. Tutaj przykładowo założyłem, że korzystasz ze Swinga zamiast AWT i zasugerowałem nadpisanie metody paintComponent(Graphics), a ta metoda istnieje wyłącznie w Swingu. W efekcie Twój kod w ogóle się nie wykonywał. W przypadku AWT powinieneś nadpisywać właśnie metodę paint().
5. By wymusić zaktualizowanie interfejsu wystarczy wywołanie repaint(), jednakże dla ciężkich komponentów (m. in. Panel czy Frame) ta metoda jedynie ustawia wewnętrzną flagę, zaś samo przemalowanie może nastąpić dużo później (
patrz dokumentacja).
Bezpośrednio w AWT nie projektowałem nigdy interfejsu i nie wiem jak wymusić przemalowanie ciężkich komponentów - odpowiedź zapewne będzie tutaj:
http://www.oracle.com/technetwork/java/index.htmlKilka uwag:
1. Zamiast implementować cały interfejs MouseListener, możesz skorzystać z dziedziczenia po anonimowej klasie MouseAdapter i nadpisać w niej jedynie pożądane metody. Tak jak to zrobiłeś w przypadku listenera dla okna (WindowAdapter).
2. Metoda z głównej klasy, która ustawia błędy jest wywoływana z poziomu wątku od UI, stąd powinna zawierać jedynie lekki kod. Jeżeli chciałbyś tam wrzucić jakieś bardziej skomplikowane zadanie, powinieneś to zrobić w osobnym wątku by interfejs programu nie zawiesił się. Google: SwingWorkers.
Tutaj masz przykład jak można to zrobić normalnie, wykorzystując JLabela oraz nadpisując paintComponent()
package net.minecraft;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FixedLauncherFrame
extends JFrame { private static final long serialVersionUID = 1L;
private FixedLoginForm loginForm;
private FixedLauncherFrame() {
loginForm = new FixedLoginForm(this);
setContentPane(loginForm);
}
public void doSomething(boolean useLabel) {
if (useLabel) {
loginForm.
errorLabel.
setText("Blah: " + System.
currentTimeMillis()); } else {
loginForm.
errorMessage = "Blah: " + System.
currentTimeMillis();
loginForm.repaint();
}
}
public static void main
(String[] args
) { @Override
public void run() {
FixedLauncherFrame frame = new FixedLauncherFrame();
frame.
setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
});
}
}
package net.minecraft;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class FixedLoginForm
extends JPanel { private static final long serialVersionUID = 1L;
private final FixedLauncherFrame launcher;
private Image backgroundImage
;
public FixedLoginForm(FixedLauncherFrame fixedLauncherFrame) {
this.launcher = fixedLauncherFrame;
try {
backgroundImage = ImageIO.read(getClass().getResourceAsStream("bg.png"));
setForeground
(Color.
WHITE);
errorLabel.
setForeground(Color.
RED);
@Override
launcher.doSomething(true);
} else {
launcher.doSomething(false);
}
}
});
}
@Override
protected void paintComponent
(Graphics g
) { super.paintComponent(g);
if (backgroundImage != null) {
g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);
}
g.setColor(getForeground());
g.
drawString("Test: " + System.
currentTimeMillis(), 50, 50
);
if (errorMessage != null) {
g.drawString("Err: " + errorMessage, 50, 75);
}
}
}
PS. Ten kod miesza ze sobą logikę aplikacji z jej interfejsem, co przy większych aplikacjach jest bardzo złą praktyką.