JFrame Pack () und requestFocus () funktionieren nicht
-
21-12-2019 - |
Frage
Mein Hauptproblem ist der folgende Code beim Einrichten eines JFrame
:
Warum wird das Panel nicht angezeigt, wenn ich das benutze
pack()
und wie funktioniert es?Warum der erste
requestFocusInWindow()
funktioniert nicht und was ist das Prinzip, es zu benutzen?Warum der Standard-Layout-Manager von
JPanel
funktioniert nicht, wenn ich das löschesetLayout()
?
public class SoundGUI extends KeyAdapter{
public static void main(String[] args) {
SoundGUI sGUI = new SoundGUI();
sGUI.setUp();
}
public void setUp () {
JFrame frame = new JFrame ("Key test");
frame.setSize (1000, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible (true);
Panel p = new Panel ();
p.setLayout(new BorderLayout());//why this sentence is necessary FlowLayout doesn't fill the container but rather lets components size to their preferredSizes.
p.addKeyListener (this);
p.requestFocusInWindow();//it's useless here
//requestFocus only works on focusable components that are displayed.
MyDrawPanel dp = new MyDrawPanel();
dp.setBackground(Color.darkGray);
JLabel test = new JLabel("a trial");
JButton t = new JButton("b");
dp.add(t);
dp.add (test);
p.add (dp);
frame.getContentPane().add(p);
p.requestFocusInWindow();
//frame.pack();//why it doesn't work
//frame.setVisible(true);
}
class MyDrawPanel extends JPanel {
public void paintComponent (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.white);
for (int i = 0; i < 1000; i += 42) {
g2.fill3DRect(i,100 ,20 ,80 ,true);
}
g2.setColor(Color.black);
for (int i = 21; i < 1000; i += 42) {
g2.fill3DRect(i,100 ,20 ,80 ,true);
}
}
}
}
Lösung
Vorschlag:
- Nennen
setVisible(true)
nach Aufrufpack()
.Macht Sinn, nicht wahr? - Das BorderLayout weist das MyDrawPanel an, den p-Container zu füllen, da die Komponente standardmäßig hinzugefügt wird (dh BorderLayout.CENTER), und so funktioniert BorderLayout.
- FlowLayout füllt den Container nicht, sondern lässt die Größe der Komponenten auf ihre bevorzugten Größen zu.
- Mischen Sie Swing nicht mit AWT-Komponenten.dh verwenden Sie keine Panels, sondern JPanels .
- requestFocus funktioniert nur bei fokussierbaren Komponenten, die angezeigt werden.
- Verwenden Sie besser Tastenbelegungen als KeyListener.
- Vermeiden Sie es nach Möglichkeit, die Größe von irgendetwas festzulegen.
Basierend auf Ihrem neuen Code liegt Ihr Problem daran, dass Sie anrufen setSize()
.Die meisten Layout-Manager respektieren dies nicht, sondern die bevorzugte Größe.Wenn Ihr Zeichnungs-JPanel so groß sein muss, dann machen Sie es so.Zum Beispiel versuchen:
class MyDrawPanel extends JPanel {
private static final int PREF_W = 1000;
private static final int PREF_H = 300;
public void paintComponent(Graphics g) {
super.paintComponent(g); //!! ******** don't forget this!!! *********
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.white);
for (int i = 0; i < 1000; i += 42) {
g2.fill3DRect(i, 100, 20, 80, true);
}
g2.setColor(Color.black);
for (int i = 21; i < 1000; i += 42) {
g2.fill3DRect(i, 100, 20, 80, true);
}
}
// the getPReferredSize will make this JPanel preferentially be this size
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Beachten Sie auch, dass Anforderungsfokus tun arbeiten, wenn das Bauteil fokussierbar ist:
JPanel p = new JPanel(); //!! This should be a JPanel, not a Panel
p.setFocusable(true); //!! This is needed
p.setLayout(new BorderLayout());
p.addKeyListener(this);
p.requestFocusInWindow();
Beachten Sie aber auch, dass KeyListener vermieden werden sollten.Verwenden Sie stattdessen Tastenbelegungen.