Hallo Leute,
ich bin neu hier und suche eine Lösung für ein kleines Problemchen, dem ich partout nicht auf die Schliche komme. Dieses Forum scheint mir dafür am geeignetsten.
Folgende Situation:
Ich "muss" eine Art Schachspiel inkl. UI programmieren. Derzeit habe ich mehrere Model-Klassen, einige Mouselistener und eben die View mit Swing.
Ich weiß jetzt nicht genau, wie ich die gesamte Situation erklären soll, von daher versuche ich es mal möglichst einfach zu halten.
Die View stellt ein Schachbrett dar, auf welches Figuren entsprechend ihrem Vorhandensein in der Board-Klasse des Models gezeichnet werden. Das alles geschieht mit der paintComponent()-Methode, die ich überschreibe.
Ein repaint des Panels, welches das Spielbrett zeichnet, geschieht durch die unterschiedlichen Mouselistener, z.B. durch MouseReleased.
Das Problem bei mir ist, dass nur unter Windows XP, ein erstmaliges MousePress, also ein Klick und dann festhalten, das Flackern des Panels auslöst. Unter Windows 7 geschieht dies nicht. Außerdem ist es egal welche Java-Version zum Einsatz kommt. (Java 6 und 7 getestet)
Dies passiert wirklich nur beim allerersten Klick, danach nicht wieder.
Nachdem das Panel einmal geflackert hat, wird augenscheinlich sofort ein repaint() durchgeführt, obwohl ich diesen nicht durch MousePressed auslösen lasse.
Das alles ist sicherlich schwer zu erklären und auch schwer nachzuvollziehen, deswegen werde ich ein Video des gesamten Problems anfügen.
knightsjava - YouTube
Desweiteren ein bisschen Code, der hoffentlich verständlich ist. Ich bin noch nicht sonderlich geübt im sinnvollen Strukturieren, von daher bitte nicht alles niedermachen.
Die Controller, also die Listener:
Der MouseMotionListener:
Und die Klasse BoardGraphic (das Panel, in dem alles gezeichnet wird):
Ich hoffe, das war jetzt nicht zu viel Code, aber da ich nicht weiß, was genau das Problem auslösen könnte, weiß ich nicht, wo ich etwas eingrenzen kann.
Ich danke schon einmal im Voraus für kompetente Hilfe!
ich bin neu hier und suche eine Lösung für ein kleines Problemchen, dem ich partout nicht auf die Schliche komme. Dieses Forum scheint mir dafür am geeignetsten.
Folgende Situation:
Ich "muss" eine Art Schachspiel inkl. UI programmieren. Derzeit habe ich mehrere Model-Klassen, einige Mouselistener und eben die View mit Swing.
Ich weiß jetzt nicht genau, wie ich die gesamte Situation erklären soll, von daher versuche ich es mal möglichst einfach zu halten.
Die View stellt ein Schachbrett dar, auf welches Figuren entsprechend ihrem Vorhandensein in der Board-Klasse des Models gezeichnet werden. Das alles geschieht mit der paintComponent()-Methode, die ich überschreibe.
Ein repaint des Panels, welches das Spielbrett zeichnet, geschieht durch die unterschiedlichen Mouselistener, z.B. durch MouseReleased.
Das Problem bei mir ist, dass nur unter Windows XP, ein erstmaliges MousePress, also ein Klick und dann festhalten, das Flackern des Panels auslöst. Unter Windows 7 geschieht dies nicht. Außerdem ist es egal welche Java-Version zum Einsatz kommt. (Java 6 und 7 getestet)
Dies passiert wirklich nur beim allerersten Klick, danach nicht wieder.
Nachdem das Panel einmal geflackert hat, wird augenscheinlich sofort ein repaint() durchgeführt, obwohl ich diesen nicht durch MousePressed auslösen lasse.
Das alles ist sicherlich schwer zu erklären und auch schwer nachzuvollziehen, deswegen werde ich ein Video des gesamten Problems anfügen.
knightsjava - YouTube
Desweiteren ein bisschen Code, der hoffentlich verständlich ist. Ich bin noch nicht sonderlich geübt im sinnvollen Strukturieren, von daher bitte nicht alles niedermachen.
Die Controller, also die Listener:
Java:
public class Mouselistener implements MouseListener{
BoardGraphic panel;
boolean hasPiece = false;
public Mouselistener(BoardGraphic panel){
this.panel = panel;
}
@Override
public void mousePressed(MouseEvent event) {
int xCoord = event.getX();
int yCoord = event.getY();
// panel.setDrawDragX(event.getX());
// panel.setDrawDragY(event.getY());
Game currentgame = GameManager.getInstance().getCurrentGame();
if (xCoord > (this.panel.getWidth() / 2 - 280)
&& xCoord < (this.panel.getWidth() / 2 + 280)
&& yCoord > (this.panel.getHeight() / 2 - 280)
&& yCoord < (this.panel.getHeight() / 2 + 280)) {
panel.setIsDragging(true);
int[] pos = this.panel.getPositionOnBoard(xCoord, yCoord);
// Initialisieren der aktiven Spielfigur
this.hasPiece = currentgame.getBoard().hasPiece(pos[0], pos[1]);
if (this.hasPiece){
panel.initActivepiece(new ActivePiece());
panel.getActivepiece().setRow(pos[0]);
panel.getActivepiece().setCol(pos[1]);
panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0], pos[1]));
panel.getActivepiece().setPossibleFields();
panel.drawPossibleFields(panel.getGraphics());
panel.markStartField(panel.getGraphics());
panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0],pos[1]));
currentgame.getBoard().setFieldPiece(panel.getActivepiece().getRow(), panel.getActivepiece().getCol(), currentgame.getBoard().getPieceEmpty());
}
}
}
@Override
public void mouseReleased(MouseEvent event) {
panel.setIsDragging(false);
if(panel.getActivepiece() != null)
{
int xCoord = event.getX();
int yCoord = event.getY();
Game currentgame = GameManager.getInstance().getCurrentGame();
// Prüfen ob Releasepunkt innerhalb des Feldes. Wenn wahr, dann neues
// Feld mit Figur besetzen.
if (xCoord > (this.panel.getWidth() / 2 - 280)
&& xCoord < (this.panel.getWidth() / 2 + 280)
&& yCoord > (this.panel.getHeight() / 2 - 280)
&& yCoord < (this.panel.getHeight() / 2 + 280)) {
// Position für das Board-Model ermitteln
int[] pos = this.panel.getPositionOnBoard(xCoord, yCoord);
// Figur setzen
currentgame.getBoard().setFieldPiece(pos[0], pos[1],
panel.getActivepiece().getPiece());
panel.repaint();
// Activepiece "leeren"
panel.resetActivePiece();
this.hasPiece = false;
} // Falls Releasepunkt nicht innerhalb des Feldes, wird die Figur
// wieder auf das Ausgangsfeld gesetzt.
else {
currentgame.getBoard().setFieldPiece(panel.getActivepiece().getRow(),
panel.getActivepiece().getCol(),panel.getActivepiece().getPiece());
panel.setIsDragging(false);
panel.resetActivePiece();
panel.repaint();
}
}
}
}
Der MouseMotionListener:
Java:
public class MousemotionListener implements MouseMotionListener {
ActivePiece activepiece;
BoardGraphic panel;
public MousemotionListener(BoardGraphic panel){
this.panel=panel;
this.activepiece=panel.getActivepiece();
}
@Override
public void mouseDragged(MouseEvent event) {
panel.setDrawDragX(event.getX());
panel.setDrawDragY(event.getY());
panel.repaint();
}
Und die Klasse BoardGraphic (das Panel, in dem alles gezeichnet wird):
Java:
public class BoardGraphic extends JPanel {
private static final long serialVersionUID = 1L;
ActivePiece activepiece = null;
boolean isDragging = false;
int drawDragX, drawDragY = 0;
final int CELLSIZE = 80;
public BoardGraphic() {
this.setPreferredSize(new Dimension(650, 600));
this.setBackground(new Color(230, 230, 250));
this.addMouseListener(new Mouselistener(this));
this.addMouseMotionListener(new MousemotionListener(this));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int xStart = this.getWidth() / 2;
int yStart = this.getHeight() / 2;
this.setFont(g);
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (i % 2 == 0) {
if (j % 2 == 0) {
g.setColor(new Color(105, 105, 105));
} else {
g.setColor(new Color(240, 230, 140));
}
} else {
if (j % 2 == 0) {
g.setColor(new Color(240, 230, 140));
} else {
g.setColor(new Color(105, 105, 105));
}
}
g.fillRect(xStart - 280 + j * CELLSIZE, yStart - 280 + i * CELLSIZE, CELLSIZE, CELLSIZE);
}
}
// Zeilenbeschriftungen links
for (int i = 1; i < 8; i++) {
g.drawString(Integer.toString(i), xStart - 320, (yStart - 230) + (i - 1) * CELLSIZE);
}
// Zeilenbeschriftungen rechts
for (int i = 1; i < 8; i++) {
g.drawString(Integer.toString(i), xStart + 305, (yStart - 230) + (i - 1) * CELLSIZE);
}
//Spaltenbeschriftungen oben
for (int i = 1; i < 8; i++) {
char zwischen = (char) (i+96);
g.drawString(Character.toString(zwischen), xStart-250 + (i-1)* CELLSIZE, yStart-310 );
}
//Spaltenbeschriftungen unten
for (int i = 1; i < 8; i++) {
char zwischen = (char) (i+96);
g.drawString(Character.toString(zwischen), xStart-240 + (i-1)* CELLSIZE, yStart+320 );
}
drawPiece(xStart, yStart, g);
if (this.isDragging == true && this.activepiece != null) {
markStartField(g);
drawPossibleFields(g);
drawPieceWhileDragging(this.drawDragX, this.drawDragY, g);
}
}
void drawPiece(int w, int h, Graphics g) {
Game currentgame = GameManager.getInstance().getCurrentGame();
int pieceStartX = (this.getWidth() / 2);
int pieceStartY = (this.getHeight() / 2);
for (int i = 0; i <currentgame.getBoard().getRows(); i++) {
for (int j = 0; j < currentgame.getBoard().getCols(); j++) {
if (currentgame.getBoard().getFieldPiece(i, j) == currentgame.getBoard().getPlayerAPiece()) {
g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerAPiece()),
(pieceStartX - 280) + j * CELLSIZE, pieceStartY - (280 - i * CELLSIZE), this);
} else if (currentgame.getBoard().getFieldPiece(i, j) == currentgame.getBoard().getPlayerBPiece()) {
g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerBPiece()),
(pieceStartX - 280) + j * CELLSIZE, pieceStartY - (280 - i * CELLSIZE), this);
}
}
}
}
void drawPieceWhileDragging(int drawDragX, int drawDragY, Graphics g) {
Game currentgame = GameManager.getInstance().getCurrentGame();
if (this.activepiece.getPiece() == currentgame.getBoard().getPlayerAPiece()) {
// Mauszeiger folgen
g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerAPiece()),
drawDragX - 30, drawDragY - 30, this);
}
if (this.activepiece.getPiece() == currentgame.getBoard().getPlayerBPiece()) {
// Mauszeiger folgen
g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerBPiece()),
drawDragX - 30, drawDragY - 30, this);
}
}
public int[] getPositionOnBoard(int xCoord, int yCoord) {
Game currentgame = GameManager.getInstance().getCurrentGame();
int xStart = this.getWidth() / 2;
int yStart = this.getHeight() / 2;
int[] position = new int[2];
for (int i = 0; i < currentgame.getBoard().getRows(); i++) {
for (int j = 0; j < currentgame.getBoard().getCols(); j++) {
// Spalten!!
if (xCoord > (xStart - 280) + j * CELLSIZE
&& xCoord < (xStart - 280) + (j + 1) * CELLSIZE) {
// Zeilen!!
if (yCoord > (yStart - 280) + i * CELLSIZE
&& yCoord < (yStart - 280) + (i + 1) * CELLSIZE) {
position[0] = i;
position[1] = j;
}
}
}
}
return position;
}
public void drawPossibleFields(Graphics g) {
for (int i = 0; i < this.activepiece.getPossibleFields().length; i++) {
drawRectangles(this.activepiece.getPossibleFields()[i].getRow()-1,
this.activepiece.getPossibleFields()[i].getCol() - 97, Color.GREEN, g);
}
}
public void drawRectangles(int row, int col, Color color, Graphics g) {
int xStart = this.getWidth() / 2;
int yStart = this.getHeight() / 2;
for (int j = 0; j < 4; j++) {
g.setColor(color);
g.drawRect((xStart - 280 + j) + (col) * CELLSIZE,
(yStart - 280 + j) + (row) * CELLSIZE,
CELLSIZE - 2 * j, CELLSIZE - 2 * j);
}
}
public void markStartField(Graphics g) {
drawRectangles(this.activepiece.getRow(), this.activepiece.getCol(), Color.BLUE, g);
}
Image loadPieceImages(char piece) {
BufferedImage image = null;
if (piece == GameManager.getInstance().getCurrentGame().getBoard().getPlayerAPiece()) {
try {
image = ImageIO.read(new File("pieces/jumper_black.png"));
} catch (IOException e) {
e.printStackTrace();
}
} else if (piece == GameManager.getInstance().getCurrentGame().getBoard().getPlayerBPiece()) {
try {
image = ImageIO.read(new File("pieces/jumper_white.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
return image;
}
public ActivePiece getActivepiece() {
return this.activepiece;
}
public void initActivepiece(ActivePiece activepiece) {
this.activepiece = activepiece;
}
public boolean getIsDragging() {
return this.isDragging;
}
public void setIsDragging(boolean isDragging) {
this.isDragging = isDragging;
}
public void setDrawDragX(int drawDragX) {
this.drawDragX = drawDragX;
}
public void setDrawDragY(int drawDragY) {
this.drawDragY = drawDragY;
}
public void resetActivePiece(){
this.activepiece = null;
}
Font setFont(Graphics g){
Font text;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.getAvailableFontFamilyNames();
text = new Font("Arial", Font.BOLD, 25);
g.setFont(text);
g.setColor(Color.black);
return text;
}
}
Ich hoffe, das war jetzt nicht zu viel Code, aber da ich nicht weiß, was genau das Problem auslösen könnte, weiß ich nicht, wo ich etwas eingrenzen kann.
Ich danke schon einmal im Voraus für kompetente Hilfe!