J'ai récemment commencé à utiliser l'interface graphique Java - le plus correctement Swing.GroupLayout fait que l'écouteur d'action perd le focus
Maintenant j'ai eu ce problème que je ne peux pas me déplacer. Je veux disposer d'un plateau de jeu qui s'étend JPanel
et met en œuvre ActionListener
(quelque chose) comme ceci:
+----------------+
| Panel1 | Board |
|________| |
| Panel2 | |
| | |
+----------------+
Mais je reçois ceci:
+----------------+
| Panel1 | Board |
|________|_______|
| Panel2 | EMPTY |
| | |
+----------------+
j'ai commencé en essayant de le faire en utilisant la GridLayout
pour le volet principal avec BoxLayout
ed panneaux à l'intérieur, mais cela n'a pas fonctionné. Ensuite, j'ai trouvé GroupLayout
, qui m'a conduit à l'affaire ci-dessus et m'a fait perdre le contrôle/la concentration de mon auditeur à l'intérieur de la classe du conseil.
[EDIT] J'ai également essayé de changer les tailles minimun et préféré de la planche, n'a pas travaillé non plus.
Quelqu'un peut-il me dire pourquoi cela se produit?
Reprise:
- Pourquoi la disposition du groupe qui fait cela au comité de la Commission? De toute façon je peux le réparer?
- Depuis l'intérieur de la classe Board je fais setFocusable (true); pourquoi ne peut-il obtenir des actions/événements après avoir été dans la disposition du groupe (fonctionne très bien sans lui)
Voici le code:
Jeu classe
...
public ConstructorOfTheClassThatExtendsJFrame() {
statusbar = new JLabel(" 0");
panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.black));
this.getContentPane().add(panel);
Board board = new Board(this);
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
//Specify automatic gap insertion:
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
//PANEL 1
col1 = new JPanel();
col1.setBorder(BorderFactory.createLineBorder(Color.black));
//PANEL 3
col3 = new JPanel();
col3.add(statusbar);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(col1)
.addComponent(col3))
.addComponent(board)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(col1)
.addComponent(board))
.addComponent(col3)
);
setSize(400, 400);
setResizable(false);
setTitle("GameOn");
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
et ma classe Conseil (de ZetCode)
public Board(Game parent) {
setFocusable(true);
curPiece = new Shape();
timer = new Timer(400, this);
timer.start();
statusbar = parent.getStatusBar();
board = new Tetrominoes[BoardWidth * BoardHeight];
addKeyListener(new TAdapter());
clearBoard();
}
...
class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (!isStarted || curPiece.getShape() == Tetrominoes.NoShape) {
return;
}
int keycode = e.getKeyCode();
if (keycode == 'p' || keycode == 'P') {
pause();
return;
}
if (isPaused)
return;
switch (keycode) {
case KeyEvent.VK_LEFT:
tryMove(curPiece, curX - 1, curY);
break;
case KeyEvent.VK_RIGHT:
tryMove(curPiece, curX + 1, curY);
break;
case KeyEvent.VK_DOWN:
//tryMove(curPiece, curX, curY - 1);
oneLineDown();
break;
case KeyEvent.VK_UP:
tryMove(curPiece.rotateRight(), curX, curY);
break;
case KeyEvent.VK_SPACE:
dropDown();
break;
case 'd':
oneLineDown();
break;
case 'D':
oneLineDown();
break;
case KeyEvent.VK_SHIFT:
newPiece();
break;
}
}
[EDIT] Après som e conseil, voici une version sscce du code où les événements clés fonctionnent, mais l'alignement est toujours mal:
La classe de jeu (ce cas est Bonjour tout le monde, mais encore)
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Color;
public class HelloWorldSwing{
private static void createAndShowGUI(){
//Create frame
JFrame frame = new JFrame("HelloWorldSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createLineBorder(Color.black));
frame.getContentPane().add(panel);
//Create the new group layout
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
//We specify automatic gap insertion:
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
//PANEL 1
JPanel col1 = new JPanel();
col1.setBorder(BorderFactory.createLineBorder(Color.black));
//PANEL 2
JLabel label2 = new JLabel("Col2");
Board board = new Board(label2, new BorderLayout());
//PANEL 3
JPanel col3 = new JPanel();
JLabel label = new JLabel("Col1");
JLabel label3 = new JLabel("Col3");
col1.add(label);
board.add(label2,BorderLayout.PAGE_END);
col3.add(label3);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(col1)
.addComponent(col3))
.addComponent(board)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(col1)
.addComponent(board))
.addComponent(col3)
);
frame.setSize(300, 400);
frame.setVisible(true);
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Et la classe conseil:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Board extends JPanel implements ActionListener {
JLabel blabel;
public Board(JLabel label, BorderLayout b) {
super(b);
setFocusable(true);
blabel = label;
addKeyListener(new TAdapter());
}
public void actionPerformed(ActionEvent e) {
}
class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
switch (keycode) {
case KeyEvent.VK_LEFT:
blabel.setText("Left");
break;
case KeyEvent.VK_RIGHT:
blabel.setText("Right");
break;
case KeyEvent.VK_DOWN:
blabel.setText("Down");
break;
}
}
}
}
Merci pour votre temps!
Envisagez de créer et d'afficher un [sscce] (http://sscce.org). Cela me rend suspicieux quand je vois des JPanels qui nécessitent une attention particulière. Pourquoi est-ce nécessaire? Et pourquoi la classe GUI implémente-t-elle l'interface d'écoute? Habituellement, votre code est plus facile à maintenir si ceux-ci sont conservés séparément. –
Et une mise en page ne devrait pas affecter les événements ActionListener, je dois donc me demander si quelque chose d'autre est différent ou faux. C'est difficile pour moi de le dire sur la base des informations que vous avez présentées jusqu'ici, c'est pourquoi le [sscce] (http://sscce.org) aiderait * énormément *. –
A propos de sscce, je ne pense pas que je peux le minimiser plus que je l'ai fait. Le texte est flou, mais c'est à cause de mon anglais, je ne peux pas m'exprimer plus court (je pense). De toute façon, si vous pensez toujours que c'est trop grand et pas "concis" dites-moi et je ferai de mon mieux. A propos de l'écouteur d'implémentation de l'interface graphique, il s'agit d'un tetris rapide que je programme. Pas de modèle MVC ou Command-Kernel, 'hard code', je suppose. –