I have a problem with GUI. In my drawing simulator, I created a JLabel that show mouseclicks coordinates. I put it on southwest of my JFrame but after each click, in addition to its first place, mouse coordinates also appear on northwest of the JFrame. I didn't understand what ths problem is.The code is here.
JLabel statusBar = new JLabel( "Mouse outside JPanel" );
Container panel;
JFrame frame = new JFrame();
panel = frame.getContentPane();
panel.add(this);
frame.setJMenuBar(jmb);
frame.add(statusBar, BorderLayout.SOUTH );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,700);
frame.setVisible(true);
This is how I edit JLabel
statusBar.setText( String.format( "Clicked at [%d, %d]",
e.getX(), e.getY() ) );
The whole code can be longer thats why iam copying some important parts
public class Tester extends JPanel implements MouseMotionListener, MouseListener {
....
This is how a draw a single line and I set the label's name here
else if(lineci == true){
if(mouseclicks == 0){
l1.point1.x = e.getX();
l1.point1.y = e.getY();
statusBar.setText( String.format( "Clicked at [%d, %d]",
e.getX(), e.getY() ) );
mouseclicks++;
}
else if(mouseclicks == 1){
l1.point2.x = e.getX();
l1.point2.y = e.getY();
statusBar.setText( String.format( "Clicked at [%d, %d]",
e.getX(), e.getY() ) );
mouseclicks = 0;
int a = l1.point2.y - l1.point1.y;
int b = l1.point1.x - l1.point2.x;
int c = (l1.point2.x * l1.point1.y) - (l1.point1.x * l1.point2.y);
l1.denklem[0] = a;
l1.denklem[1] = b;
l1.denklem[2] = c;
array.add(l1);
array3.add(l1);
repaint();
}
By the way, I 'm creating JLabel object outside the constructur of the class, just after creating class I mean.
Still same problem exists.
Instead of
frame.add(statusBar, BorderLayout.SOUTH );
Try
frame.getContentPane().add(statusBar, BorderLayout.SOUTH );
Related
I am working on developing a Chess game. I want to have the board Container utilize a GridLayout to display an 8x8 grid of JPanels. (This will make functions such as highlighting selected squares and valid moves much easier.) I would then like to add the pieces over this layer so that they may be dragged and dropped. I initially had the pieces showing by drawing them in the individual square JPanels, but figured that would be a problem when trying to drag-and-drop them later. I have since been trying to use a JLayeredPane as the main container, but have encountered several issues.
One is that once I've specified the GridLayout for the JLayeredPane, regardless of which Integer I use to specify the layer to add the JLabel or other kind of image to, the pieces get added to the grid, making their positions set and and distorting the whole board. I have read that using LayoutManagers can interfere with layer positioning on the JLayeredPane, so this isn't too surprising. (Although the Oracle demo program from the JLayeredPane tutorial seems to do this just fine: http://download.oracle.com/javase/tutorial/uiswing/examples/components/LayeredPaneDemo2Project/src/components/LayeredPaneDemo2.java)
However, I have also tried to put the grid of JPanels into its own JPanel, then add it to a low layer of the JLayeredPane, the idea being that I could add the drag & drop icons to separate, non-opaque JPanel on a higher layer of the JLayeredPane. When I do this however, after I simply have the grid JPanel inside the JLayeredPane (i.e. before the drag-and-drop layer is added), the grid will not display.
I also have tried overriding the paintComponent (and paint) methods of the JLayeredPane to draw the piece images, but they are hidden by the JPanels (I can see that they are indeed there by setting the JPanels to non-opaque) and as far as I can tell there is no option to set the layer of the graphics on the JLayeredPane. I have also tried using the glassPane of the frame to draw the pieces, but got undesired behavior there as well.
Any help explaining some of this behavior, or where I am going wrong, would be much appreciated!
Here is a simple example that shows how you might (randomly) drag and drop a "chess piece" from one square to another:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener
{
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
public ChessBoard()
{
Dimension boardSize = new Dimension(600, 600);
// Use a Layered Pane for this this application
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize( boardSize );
layeredPane.addMouseListener( this );
layeredPane.addMouseMotionListener( this );
getContentPane().add(layeredPane);
// Add a chess board to the Layered Pane
chessBoard = new JPanel();
chessBoard.setLayout( new GridLayout(8, 8) );
chessBoard.setPreferredSize( boardSize );
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
// Build the Chess Board squares
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
JPanel square = new JPanel( new BorderLayout() );
square.setBackground( (i + j) % 2 == 0 ? Color.red : Color.white );
chessBoard.add( square );
}
}
// Add a few pieces to the board
ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here
JLabel piece = new JLabel( duke );
JPanel panel = (JPanel)chessBoard.getComponent( 0 );
panel.add( piece );
piece = new JLabel( duke );
panel = (JPanel)chessBoard.getComponent( 15 );
panel.add( piece );
}
/*
** Add the selected chess piece to the dragging layer so it can be moved
*/
public void mousePressed(MouseEvent e)
{
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel) return;
Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel)c;
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
/*
** Move the chess piece around
*/
public void mouseDragged(MouseEvent me)
{
if (chessPiece == null) return;
// The drag location should be within the bounds of the chess board
int x = me.getX() + xAdjustment;
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
x = Math.min(x, xMax);
x = Math.max(x, 0);
int y = me.getY() + yAdjustment;
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
y = Math.min(y, yMax);
y = Math.max(y, 0);
chessPiece.setLocation(x, y);
}
/*
** Drop the chess piece back onto the chess board
*/
public void mouseReleased(MouseEvent e)
{
layeredPane.setCursor(null);
if (chessPiece == null) return;
// Make sure the chess piece is no longer painted on the layered pane
chessPiece.setVisible(false);
layeredPane.remove(chessPiece);
chessPiece.setVisible(true);
// The drop location should be within the bounds of the chess board
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
int x = Math.min(e.getX(), xMax);
x = Math.max(x, 0);
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
int y = Math.min(e.getY(), yMax);
y = Math.max(y, 0);
Component c = chessBoard.findComponentAt(x, y);
if (c instanceof JLabel)
{
Container parent = c.getParent();
parent.remove(0);
parent.add( chessPiece );
parent.validate();
}
else
{
Container parent = (Container)c;
parent.add( chessPiece );
parent.validate();
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public static void main(String[] args)
{
JFrame frame = new ChessBoard();
frame.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
frame.setResizable( false );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
My program here is designed to create a GUI that allows the user to draw shapes on it by clicking and releasing the mouse on a JPanel. Further options include changing color and whether or not the shape is filled. Once a shape is drawn, the other options should redraw the same shape, with any new modifiers. For instance, if I draw a red rectangle, if I go to choose the color blue, the rectangle should just change color. I have thus far only implemented the "rectangle" option.
My mouseListner correctly captures and stores values, paintComponent() draws a rectangle when values are hardcoded in (I have commented out the sections in paintComponent(), but I am initializing my coordinate variables for simplicity), and a series of System.out.println() show that the program goes through the order of capturing the mouse pressed, the mouse released, calling paintComponent(), all the way down to the actual g.drawRect() methods. I am 100% positive the values aren't being clobbered, as I can print the correct values before I try and draw a shape. I suspect the problem is with drawing more than one shape, but even then, when I hardcode values in and change the color of the shape, I am effectively drawing a new shape, not changing the old one.
Help.
public class WardA4 extends JFrame implements ActionListener{
private String[] chooseShapeOptions = {"Rectangle", "Square", "Oval", "Circle", "Line",
"Rounded Rectangle", "3D Rectangle"};
private JCheckBox chooseFill;
private JComboBox chooseShape;
private JButton chooseColor;
private JPanel userInterface, displayPanel;
private JLabel chooseFillLabel, chooseColorLabel;
private Color color = Color.WHITE;
private int shapeIndex = 0;
private double xStart = 100, yStart = 100, xEnd = 200, yEnd = 200;
private boolean isFilled;
public WardA4(){
super("Sandbox");
chooseShape = new JComboBox(chooseShapeOptions);
chooseFill = new JCheckBox();
chooseColor = new JButton();
chooseFillLabel = new JLabel("Fill");
chooseColorLabel = new JLabel ("Color");
userInterface = new JPanel(new FlowLayout());
userInterface.add(chooseShape);
userInterface.add(chooseFillLabel);
userInterface.add(chooseFill);
userInterface.add(chooseColorLabel);
userInterface.add(chooseColor);
displayPanel = new JPanel(){
public void paintComponent (Graphics g){
super.paintComponent(g);
System.out.println("Entering paint component");
System.out.println("starting coordinates are (" + xStart + "," + yStart + ")\n width is " + (int)Math.abs(xStart-xEnd) + "\n height is " + (int)Math.abs(yStart-yEnd));
g.setColor(color);
//System.out.println("" + (int)xStart + " " + (int)yStart + " " + (int)Math.abs(xStart-xEnd) + " " + (int)Math.abs(yStart-yEnd));
switch(shapeIndex){
case 0:
if(isFilled){
System.out.println("Entering is filled");
g.fillRect((int)xStart, (int)yStart, (int)Math.abs(xStart-xEnd), (int)Math.abs(yStart-yEnd));
//g.fillRect(100,100,100,100);
}
else{
System.out.println("Entering is not filled");
g.drawRect((int)xStart, (int)yStart, (int)Math.abs(xStart-xEnd), (int)Math.abs(yStart-yEnd));
//g.drawRect(100,100,100,100);
}
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
}
}
};
displayPanel.setBackground(Color.BLACK);
add(displayPanel, BorderLayout.CENTER);
add(userInterface, BorderLayout.SOUTH);
chooseShape.addActionListener(this);
chooseFill.addActionListener(this);
chooseColor.addActionListener(this);
displayPanel.addMouseListener(new MouseAdapter(){
public void mousePressed (MouseEvent me){
System.out.println("Entering mouse pressed");
xStart = MouseInfo.getPointerInfo().getLocation().getX();
yStart = MouseInfo.getPointerInfo().getLocation().getY();
System.out.println("mouse pressed at (" + xStart + "," + yStart + ")");
}
public void mouseReleased (MouseEvent me){
System.out.println("Entering mouse released");
xEnd = MouseInfo.getPointerInfo().getLocation().getX();
yEnd = MouseInfo.getPointerInfo().getLocation().getY();
System.out.println("mouse released at (" + xEnd + "," + yEnd + ")");
repaint();
}
});
}
public void actionPerformed(ActionEvent e){
if (e.getSource() == chooseShape){
shapeIndex = chooseShape.getSelectedIndex();
}
else if (e.getSource() == chooseFill){
isFilled = chooseFill.isSelected();
}
else if (e.getSource() == chooseColor){
color = JColorChooser.showDialog(null, "Choose color", color);
if (color == null)
color = Color.WHITE;
}
repaint();
}
public static void main(String[] args) {
WardA4 frame = new WardA4();
frame.setSize(400,300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
}
An example output, where I press around on the panel a couple times:
Entering paint component
starting coordinates are (100.0,100.0)
width is 100
height is 100
Entering is not filled
Entering paint component
starting coordinates are (100.0,100.0)
width is 100
height is 100
Entering is not filled
Entering mouse pressed
mouse pressed at (906.0,449.0)
Entering mouse released
mouse released at (1092.0,612.0)
Entering paint component
starting coordinates are (906.0,449.0)
width is 186
height is 163
Entering is not filled
Entering mouse pressed
mouse pressed at (1092.0,612.0)
Entering mouse released
mouse released at (1092.0,612.0)
Entering paint component
starting coordinates are (1092.0,612.0)
width is 0
height is 0
Entering is not filled
The events being queried are faulty (using the wrong co-ordinates). E.G.
xStart = MouseInfo.getPointerInfo().getLocation().getX(); // gets location ON SCREEN
yStart = MouseInfo.getPointerInfo().getLocation().getY();
Should be:
xStart = me.getX(); // gets location relative TO PANEL
yStart = me.getY();
Some background I am developing a game in java, I am using Netbeans to build it I currently have 3 java files
App.java
Board.java
Piece.java
Currently When it runs it shows the user a simple chess board with all the pieces in the right positions etc.
That is all done in Board.java
My Problem is the movement for the pieces is done in Piece.java currently I have the white pawn coded and the mouse events that control it but when i run the program the board appears along with the pieces but none of the pieces move not even the white pawn
and I am stumped to as why, I think maybe I have not linked them probably with the board or something along those lines or maybe there is something u with my mouseevents
Also I am not getting any errors in my code when it run
Here are the java files
App.java
package chessgame;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class App {
public static void main(String[] args) {
JFrame frame = new Board();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE );
frame.pack();
frame.setResizable(true);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Board.java
package chessgame;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class Board extends JFrame {
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
int startX;
int startY;
int initialX;
int initialY;
JPanel panels;
JLabel pieces;
public Board() {
Dimension boardSize = new Dimension(600, 600);
// This is a Layered Pane for this application
layeredPane = new JLayeredPane();
getContentPane().add(layeredPane);
layeredPane.setPreferredSize(boardSize);
//Add a chess board to the Layered Pane
chessBoard = new JPanel();
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
chessBoard.setLayout(new GridLayout(8, 8));
chessBoard.setPreferredSize(boardSize);
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
for (int i = 0; i < 64; i++) {
JPanel square = new JPanel(new BorderLayout());
chessBoard.add(square);
int row = (i / 8) % 2;
if (row == 0) {
square.setBackground(i % 2 == 0 ? Color.white : Color.gray);
} else {
square.setBackground(i % 2 == 0 ? Color.gray : Color.white);
}
}
// Setting up the Initial Chess board.
//White Side
for (int i = 8; i < 16; i++) {
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhitePawn.png")));
panels = (JPanel) chessBoard.getComponent(i);
panels.add(pieces);
}
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteRook.png")));
panels = (JPanel) chessBoard.getComponent(0);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteKnight.png")));
panels = (JPanel) chessBoard.getComponent(1);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteKnight.png")));
panels = (JPanel) chessBoard.getComponent(6);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteBishup.png")));
panels = (JPanel) chessBoard.getComponent(2);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteBishup.png")));
panels = (JPanel) chessBoard.getComponent(5);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteKing.png")));
panels = (JPanel) chessBoard.getComponent(3);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteQueen.png")));
panels = (JPanel) chessBoard.getComponent(4);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteRook.png")));
panels = (JPanel) chessBoard.getComponent(7);
panels.add(pieces);
//Black Side
for (int i = 48; i < 56; i++) {
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackPawn.png")));
panels = (JPanel) chessBoard.getComponent(i);
panels.add(pieces);
}
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackRook.png")));
panels = (JPanel) chessBoard.getComponent(56);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackKnight.png")));
panels = (JPanel) chessBoard.getComponent(57);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackKnight.png")));
panels = (JPanel) chessBoard.getComponent(62);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackBishup.png")));
panels = (JPanel) chessBoard.getComponent(58);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackBishup.png")));
panels = (JPanel) chessBoard.getComponent(61);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackKing.png")));
panels = (JPanel) chessBoard.getComponent(59);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackQueen.png")));
panels = (JPanel) chessBoard.getComponent(60);
panels.add(pieces);
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/BlackRook.png")));
panels = (JPanel) chessBoard.getComponent(63);
panels.add(pieces);
}
}
Piece.java
package chessgame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Piece extends JLabel implements MouseListener, MouseMotionListener {
public Piece(ImageIcon icon) { super(icon); }
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
int startX;
int startY;
int initialX;
int initialY;
JPanel panels;
JLabel pieces;
/*
This method checks if there is a piece present on a particular square.
*/
private Boolean piecePresent(int x, int y) {
Component c = chessBoard.findComponentAt(x, y);
if (c instanceof JPanel) {
return false;
} else {
return true;
}
}
/*
This is a method to check if a piece is a Black piece.
*/
private Boolean checkWhiteOponent(int newX, int newY) {
Boolean oponent;
Component c1 = chessBoard.findComponentAt(newX, newY);
JLabel awaitingPiece = (JLabel) c1;
String tmp1 = awaitingPiece.getIcon().toString();
if (((tmp1.contains("Black")))) {
oponent = true;
} else {
oponent = false;
}
return oponent;
}
/*
This method is called when we press the Mouse. So we need to find out what piece we have
selected. We may also not have selected a piece!
*/
public void mousePressed(MouseEvent e) {
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel) {
return;
}
Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel) c;
initialX = e.getX();
initialY = e.getY();
startX = (e.getX() / 75);
startY = (e.getY() / 75);
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
chessPiece.setSize(chessPiece.getWidth(), chessPiece.getHeight());
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
}
public void mouseDragged(MouseEvent me) {
if (chessPiece == null) {
return;
}
chessPiece.setLocation(me.getX() + xAdjustment, me.getY() + yAdjustment);
}
/*
This method is used when the Mouse is released...we need to make sure the move was valid before
putting the piece back on the board.
*/
public void mouseReleased(MouseEvent e) {
if (chessPiece == null) {
return;
}
chessPiece.setVisible(false);
Boolean success = false;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
String tmp = chessPiece.getIcon().toString();
String pieceName = tmp.substring(0, (tmp.length() - 4));
Boolean validMove = false;
if (pieceName.equals("WhitePawn")) {
if (startY == 1) {
if ((startX == (e.getX() / 75)) && ((((e.getY() / 75) - startY) == 1) || ((e.getY() / 75) - startY) == 2)) {
if ((((e.getY() / 75) - startY) == 2)) {
if ((!piecePresent(e.getX(), (e.getY()))) && (!piecePresent(e.getX(), (e.getY() + 75)))) {
validMove = true;
} else {
validMove = false;
}
} else {
if ((!piecePresent(e.getX(), (e.getY())))) {
validMove = true;
} else {
validMove = false;
}
}
} else {
validMove = false;
}
} else {
int newY = e.getY() / 75;
int newX = e.getX() / 75;
if ((startX - 1 >= 0) || (startX + 1 <= 7)) {
if ((piecePresent(e.getX(), (e.getY()))) && ((((newX == (startX + 1) && (startX + 1 <= 7))) || ((newX == (startX - 1)) && (startX - 1 >= 0))))) {
if (checkWhiteOponent(e.getX(), e.getY())) {
validMove = true;
if (startY == 6) {
success = true;
}
} else {
validMove = false;
}
} else {
if (!piecePresent(e.getX(), (e.getY()))) {
if ((startX == (e.getX() / 75)) && ((e.getY() / 75) - startY) == 1) {
if (startY == 6) {
success = true;
}
validMove = true;
} else {
validMove = false;
}
} else {
validMove = false;
}
}
} else {
validMove = false;
}
}
}
if (!validMove) {
int location = 0;
if (startY == 0) {
location = startX;
} else {
location = (startY * 8) + startX;
}
String pieceLocation = pieceName + ".png";
pieces = new JLabel(new ImageIcon(pieceLocation));
panels = (JPanel) chessBoard.getComponent(location);
panels.add(pieces);
} else {
if (success) {
int location = 56 + (e.getX() / 75);
if (c instanceof JLabel) {
Container parent = c.getParent();
parent.remove(0);
pieces = new JLabel(new ImageIcon("WhiteQueen.png"));
parent = (JPanel) chessBoard.getComponent(location);
parent.add(pieces);
} else {
Container parent = (Container) c;
pieces = new JLabel(new ImageIcon("WhiteQueen.png"));
parent = (JPanel) chessBoard.getComponent(location);
parent.add(pieces);
}
} else {
if (c instanceof JLabel) {
Container parent = c.getParent();
parent.remove(0);
parent.add(chessPiece);
} else {
Container parent = (Container) c;
parent.add(chessPiece);
}
chessPiece.setVisible(true);
}
}
}
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
Also here is a screenshot of the layout in netbeans
Any help or tips for would welcomed
Here is the Source File in which everything is written in one giant file the pieces can be moved and the white pawn moves right, that is how I know the piece is coded right i just can see to link the events know that they are separate
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
/*
This class can be used as a starting point for creating your Chess game project. The only piece that
has been coded is a white pawn...a lot done, more to do!
*/
public class ChessProject extends JFrame implements MouseListener, MouseMotionListener {
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
int startX;
int startY;
int initialX;
int initialY;
JPanel panels;
JLabel pieces;
public ChessProject(){
Dimension boardSize = new Dimension(600, 600);
// Use a Layered Pane for this application
layeredPane = new JLayeredPane();
getContentPane().add(layeredPane);
layeredPane.setPreferredSize(boardSize);
layeredPane.addMouseListener(this);
layeredPane.addMouseMotionListener(this);
//Add a chess board to the Layered Pane
chessBoard = new JPanel();
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
chessBoard.setLayout( new GridLayout(8, 8) );
chessBoard.setPreferredSize( boardSize );
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
for (int i = 0; i < 64; i++) {
JPanel square = new JPanel( new BorderLayout() );
chessBoard.add( square );
int row = (i / 8) % 2;
if (row == 0)
square.setBackground( i % 2 == 0 ? Color.white : Color.gray );
else
square.setBackground( i % 2 == 0 ? Color.gray : Color.white );
}
// Setting up the Initial Chess board.
for(int i=8;i < 16; i++){
pieces = new JLabel( new ImageIcon("WhitePawn.png") );
panels = (JPanel)chessBoard.getComponent(i);
panels.add(pieces);
}
pieces = new JLabel( new ImageIcon("WhiteRook.png") );
panels = (JPanel)chessBoard.getComponent(0);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteKnight.png") );
panels = (JPanel)chessBoard.getComponent(1);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteKnight.png") );
panels = (JPanel)chessBoard.getComponent(6);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteBishup.png") );
panels = (JPanel)chessBoard.getComponent(2);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteBishup.png") );
panels = (JPanel)chessBoard.getComponent(5);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteKing.png") );
panels = (JPanel)chessBoard.getComponent(3);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteQueen.png") );
panels = (JPanel)chessBoard.getComponent(4);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("WhiteRook.png") );
panels = (JPanel)chessBoard.getComponent(7);
panels.add(pieces);
for(int i=48;i < 56; i++){
pieces = new JLabel( new ImageIcon("BlackPawn.png") );
panels = (JPanel)chessBoard.getComponent(i);
panels.add(pieces);
}
pieces = new JLabel( new ImageIcon("BlackRook.png") );
panels = (JPanel)chessBoard.getComponent(56);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackKnight.png") );
panels = (JPanel)chessBoard.getComponent(57);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackKnight.png") );
panels = (JPanel)chessBoard.getComponent(62);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackBishup.png") );
panels = (JPanel)chessBoard.getComponent(58);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackBishup.png") );
panels = (JPanel)chessBoard.getComponent(61);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackKing.png") );
panels = (JPanel)chessBoard.getComponent(59);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackQueen.png") );
panels = (JPanel)chessBoard.getComponent(60);
panels.add(pieces);
pieces = new JLabel( new ImageIcon("BlackRook.png") );
panels = (JPanel)chessBoard.getComponent(63);
panels.add(pieces);
}
/*
This method checks if there is a piece present on a particular square.
*/
private Boolean piecePresent(int x, int y){
Component c = chessBoard.findComponentAt(x, y);
if(c instanceof JPanel){
return false;
}
else{
return true;
}
}
/*
This is a method to check if a piece is a Black piece.
*/
private Boolean checkWhiteOponent(int newX, int newY){
Boolean oponent;
Component c1 = chessBoard.findComponentAt(newX, newY);
JLabel awaitingPiece = (JLabel)c1;
String tmp1 = awaitingPiece.getIcon().toString();
if(((tmp1.contains("Black")))){
oponent = true;
}
else{
oponent = false;
}
return oponent;
}
/*
This method is called when we press the Mouse. So we need to find out what piece we have
selected. We may also not have selected a piece!
*/
public void mousePressed(MouseEvent e){
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel)
return;
Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel)c;
initialX = e.getX();
initialY = e.getY();
startX = (e.getX()/75);
startY = (e.getY()/75);
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
chessPiece.setSize(chessPiece.getWidth(), chessPiece.getHeight());
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
}
public void mouseDragged(MouseEvent me) {
if (chessPiece == null) return;
chessPiece.setLocation(me.getX() + xAdjustment, me.getY() + yAdjustment);
}
/*
This method is used when the Mouse is released...we need to make sure the move was valid before
putting the piece back on the board.
*/
public void mouseReleased(MouseEvent e) {
if(chessPiece == null) return;
chessPiece.setVisible(false);
Boolean success =false;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
String tmp = chessPiece.getIcon().toString();
String pieceName = tmp.substring(0, (tmp.length()-4));
Boolean validMove = false;
/*
The only piece that has been enabled to move is a White Pawn...but we should really have this is a separate
method somewhere...how would this work.
So a Pawn is able to move two squares forward one its first go but only one square after that.
The Pawn is the only piece that cannot move backwards in chess...so be careful when committing
a pawn forward. A Pawn is able to take any of the opponent’s pieces but they have to be one
square forward and one square over, i.e. in a diagonal direction from the Pawns original position.
If a Pawn makes it to the top of the other side, the Pawn can turn into any other piece, for
demonstration purposes the Pawn here turns into a Queen.
*/
if(pieceName.equals("WhitePawn")){
if(startY == 1)
{
if((startX == (e.getX()/75))&&((((e.getY()/75)-startY)==1)||((e.getY()/75)-startY)==2))
{
if((((e.getY()/75)-startY)==2)){
if((!piecePresent(e.getX(), (e.getY())))&&(!piecePresent(e.getX(), (e.getY()+75)))){
validMove = true;
}
else{
validMove = false;
}
}
else{
if((!piecePresent(e.getX(), (e.getY()))))
{
validMove = true;
}
else{
validMove = false;
}
}
}
else{
validMove = false;
}
}
else{
int newY = e.getY()/75;
int newX = e.getX()/75;
if((startX-1 >=0)||(startX +1 <=7))
{
if((piecePresent(e.getX(), (e.getY())))&&((((newX == (startX+1)&&(startX+1<=7)))||((newX == (startX-1))&&(startX-1 >=0)))))
{
if(checkWhiteOponent(e.getX(), e.getY())){
validMove = true;
if(startY == 6){
success = true;
}
}
else{
validMove = false;
}
}
else{
if(!piecePresent(e.getX(), (e.getY()))){
if((startX == (e.getX()/75))&&((e.getY()/75)-startY)==1){
if(startY == 6){
success = true;
}
validMove = true;
}
else{
validMove = false;
}
}
else{
validMove = false;
}
}
}
else{
validMove = false;
}
}
}
if(!validMove){
int location=0;
if(startY ==0){
location = startX;
}
else{
location = (startY*8)+startX;
}
String pieceLocation = pieceName+".png";
pieces = new JLabel( new ImageIcon(pieceLocation) );
panels = (JPanel)chessBoard.getComponent(location);
panels.add(pieces);
}
else{
if(success){
int location = 56 + (e.getX()/75);
if (c instanceof JLabel){
Container parent = c.getParent();
parent.remove(0);
pieces = new JLabel( new ImageIcon("WhiteQueen.png") );
parent = (JPanel)chessBoard.getComponent(location);
parent.add(pieces);
}
else{
Container parent = (Container)c;
pieces = new JLabel( new ImageIcon("WhiteQueen.png") );
parent = (JPanel)chessBoard.getComponent(location);
parent.add(pieces);
}
}
else{
if (c instanceof JLabel){
Container parent = c.getParent();
parent.remove(0);
parent.add( chessPiece );
}
else {
Container parent = (Container)c;
parent.add( chessPiece );
}
chessPiece.setVisible(true);
}
}
}
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e) {
}
/*
Main method that gets the ball moving.
*/
public static void main(String[] args) {
JFrame frame = new ChessProject();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE );
frame.pack();
frame.setResizable(true);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
You never create an instance of Piece, not even once, so it has no means by which it could ever respond to any events, it's not even on the screen...
I "think" you want to do something more like...
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteRook.png")));
...Note, you'll need to update Piece to support been constructed with a ImageIcon
There's also a bunch of issues with Piece. You have a bunch instance fields...
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
//...
JPanel panels;
JLabel pieces;
Which aren't linked to anything (they are null) which is going to cause you no end of issues.
Instead of focusing all the management within the UI, consider trying to use more of a MVC model. The game logic, rules and state should be maintain within a model, which has NO UI logic at all. It basically allows you to take a piece and make a move, validating that process as it goes. It would then provide notifications back to the UI, via an observer pattern which would notify the UI that some state has changed...
Updated...
Update the constructor of Piece so it can take a reference to an Icon and pass it onto it's parent, this way, you can continue using the code you already have...
public Piece(Icon icon) {
super(icon);
}
Next, when you create a Piece, you need to install a MouseListener to it. In this case, I'd be tempted to make the board responsible for the management of the pieces, it knows the layout and where all the pieces are...
pieces = new Piece(new ImageIcon(getClass().getResource("/chessgame/PieceImages/WhiteRook.png")));
pieces.addMouseListener(this);
I have a small GUI java program I'm working on but designing how the pieces should work together is frustrating me. Basically what I need to do is draw a "car" on a panel and attach that panel to a frame. Then animate the panel to give the illusion of movement.
My problem is that I don't understand how to move the code that does the animation to its own class. When I started working on this I made the UI elements first. Then I came across the Timer class and used that class in what was supposed to be just a UI element class (CarBody). The way my code works now is that as soon as I run the program the "car" starts moving because I don't have it set up to be triggered by a button press. I don't understand how to move the animation code to its on class and trigger it with a button press.
I could solve this in two seconds IF I could call repaint() in the performAction() method. The problem is I can't do that! It wont compile that way.
What I have done is
class CarBody extends JPanel {
private int xCoordinate = 0;
CarBody(){
Timer timer = new Timer(1000,new TimerListener());
timer.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//g.fillRect(10, 10, 60, 50);
if(xCoordinate > getWidth()){
xCoordinate = -20;
}
xCoordinate +=100;
g.fillRect(xCoordinate,10,60,50);
}
class TimerListener implements ActionListener{
public void actionPerformed(ActionEvent e){
repaint();
}
}
}
I could solve this in two seconds IF I could call repaint() in the performAction() method.
You should not be changing the car coordinates in the paintComponent() method. You should have a method that sets the coordinates and then repaints the car.
When you create the ActionListener class then pass in the panel you want to repaint as a parameter to the class. Then you can invoke the "changeLocation" method which will update the location of the car and then invoke repaint() on itself.
For another approach you can add an Icon to a label and just change the location of the label and it will repaint itself automatically. Here is a simple example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerAnimation extends JLabel implements ActionListener
{
int deltaX = 2;
int deltaY = 3;
int directionX = 1;
int directionY = 1;
public TimerAnimation(
int startX, int startY,
int deltaX, int deltaY,
int directionX, int directionY,
int delay)
{
this.deltaX = deltaX;
this.deltaY = deltaY;
this.directionX = directionX;
this.directionY = directionY;
setIcon( new ImageIcon("dukewavered.gif") );
// setIcon( new ImageIcon("copy16.gif") );
setSize( getPreferredSize() );
setLocation(startX, startY);
new javax.swing.Timer(delay, this).start();
}
public void actionPerformed(ActionEvent e)
{
Container parent = getParent();
// Determine next X position
int nextX = getLocation().x + (deltaX * directionX);
if (nextX < 0)
{
nextX = 0;
directionX *= -1;
}
if ( nextX + getSize().width > parent.getSize().width)
{
nextX = parent.getSize().width - getSize().width;
directionX *= -1;
}
// Determine next Y position
int nextY = getLocation().y + (deltaY * directionY);
if (nextY < 0)
{
nextY = 0;
directionY *= -1;
}
if ( nextY + getSize().height > parent.getSize().height)
{
nextY = parent.getSize().height - getSize().height;
directionY *= -1;
}
// Move the label
setLocation(nextX, nextY);
}
public static void main(String[] args)
{
JPanel panel = new JPanel();
JFrame frame = new JFrame();
frame.setContentPane(panel);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().setLayout(null);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
frame.getContentPane().add( new TimerAnimation(300, 100, 3, 2, -1, 1, 20) );
// frame.getContentPane().add( new TimerAnimation(0, 000, 5, 0, 1, 1, 20) );
frame.getContentPane().add( new TimerAnimation(0, 200, 5, 0, 1, 1, 80) );
frame.setSize(400, 400);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
// frame.getContentPane().add( new TimerAnimation(10, 10, 3, 0, 1, 1, 10) );
}
}
This example, doesn't do custom painting and the animation is done by invoking the setlocation(...) method on the label which will cause a repaint() so the solution is slightly different than yours, but the key point is NOT to change the location values in the paintComponent() method.
I have a subclass of JLabel that forms a component of my GUI. I have implemented the ability to drag and drop the component from one container to another, but without any visual effects. I want to have this JLabel follow the cursor during the drag of the item from one container to another. I figured that I could just create a glass pane and draw it on there. However, even after I add the component to the glass pane, set the component visible, and set the glass pane visible, and set the glass pane as opaque, I still so not see the component. I know the component works because I can add it to the content pane and have it show up.
How do I add a component to the glass pane?
Finally figured how to get the simple example working. Thanks, #akf. I was able to adapt this solution to my original problem, allowing me to remove ~60 lines of Java2D code that manually rendered a representation of the JLabel.
package test;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class MainFrame extends JFrame {
/**
* #param args
*/
public static void main(String[] args) {
MainFrame mf = new MainFrame();
mf.setSize(400, 400);
mf.setLocationRelativeTo(null);
mf.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
mf.setGlassPane(new JPanel());
JLabel l = new JLabel();
l.setText("Hello");
l.setBorder(new LineBorder(Color.BLACK, 1));
l.setBounds(10, 10, 50, 20);
l.setBackground(Color.RED);
l.setOpaque(true);
l.setPreferredSize(l.getSize());
//mf.add(l);
((JPanel)mf.getGlassPane()).add(l);
mf.getGlassPane().setVisible(true);
mf.setVisible(true);
}
}
The example code below shows how to drag a chess piece around a chess board. It uses JLayeredPane instead of a glass pane, but I'm sure the concepts would be the same. That is:
a) add the glass pane to the root pane
b) make the glass pane visible
c) add the component to the glass pane making sure the bounds are valid
d) use setLocation() to animate the dragging of the component
Edit: added code to fix SSCCE
JLabel l = new JLabel();
l.setText("Hello");
l.setBorder(new LineBorder(Color.BLACK, 1));
// l.setPreferredSize(l.getSize());
// l.setBounds(10, 10, 50, 20);
((JPanel)mf.getGlassPane()).add(l);
mf.setVisible(true);
mf.getGlassPane().setVisible(true);
When using layout managers you never use the setSize() or setBounds() methods. In your case you just set the preferred size to (0, 0) since this is the default size of all components.
It works when you add the label to the frame because the default layout manger for the content pane of the frame is a border layout, therefore the preferred size of the label is ignored and the label is made the size of the frame.
However, by default a JPanel uses a FlowLayout which does respect the preferred size of the component. Since the preferred size is 0, there is nothing to paint.
Also, the glass pane needs to made visible in order for it to be painted.
I suggest you read the Swing tutorial. There are section on how layout managers work and on how glass panes work and each section has working examples.
Edit: Example code added below:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener
{
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
public ChessBoard()
{
Dimension boardSize = new Dimension(600, 600);
// Use a Layered Pane for this this application
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize( boardSize );
layeredPane.addMouseListener( this );
layeredPane.addMouseMotionListener( this );
getContentPane().add(layeredPane);
// Add a chess board to the Layered Pane
chessBoard = new JPanel();
chessBoard.setLayout( new GridLayout(8, 8) );
chessBoard.setPreferredSize( boardSize );
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
// Build the Chess Board squares
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
JPanel square = new JPanel( new BorderLayout() );
square.setBackground( (i + j) % 2 == 0 ? Color.red : Color.white );
chessBoard.add( square );
}
}
// Add a few pieces to the board
ImageIcon duke = new ImageIcon("dukewavered.gif"); // add an image here
JLabel piece = new JLabel( duke );
JPanel panel = (JPanel)chessBoard.getComponent( 0 );
panel.add( piece );
piece = new JLabel( duke );
panel = (JPanel)chessBoard.getComponent( 15 );
panel.add( piece );
}
/*
** Add the selected chess piece to the dragging layer so it can be moved
*/
public void mousePressed(MouseEvent e)
{
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel) return;
Point parentLocation = c.getParent().getLocation();
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel)c;
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
layeredPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
/*
** Move the chess piece around
*/
public void mouseDragged(MouseEvent me)
{
if (chessPiece == null) return;
// The drag location should be within the bounds of the chess board
int x = me.getX() + xAdjustment;
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
x = Math.min(x, xMax);
x = Math.max(x, 0);
int y = me.getY() + yAdjustment;
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
y = Math.min(y, yMax);
y = Math.max(y, 0);
chessPiece.setLocation(x, y);
}
/*
** Drop the chess piece back onto the chess board
*/
public void mouseReleased(MouseEvent e)
{
layeredPane.setCursor(null);
if (chessPiece == null) return;
// Make sure the chess piece is no longer painted on the layered pane
chessPiece.setVisible(false);
layeredPane.remove(chessPiece);
chessPiece.setVisible(true);
// The drop location should be within the bounds of the chess board
int xMax = layeredPane.getWidth() - chessPiece.getWidth();
int x = Math.min(e.getX(), xMax);
x = Math.max(x, 0);
int yMax = layeredPane.getHeight() - chessPiece.getHeight();
int y = Math.min(e.getY(), yMax);
y = Math.max(y, 0);
Component c = chessBoard.findComponentAt(x, y);
if (c instanceof JLabel)
{
Container parent = c.getParent();
parent.remove(0);
parent.add( chessPiece );
parent.validate();
}
else
{
Container parent = (Container)c;
parent.add( chessPiece );
parent.validate();
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public static void main(String[] args)
{
JFrame frame = new ChessBoard();
frame.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
frame.setResizable( false );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Although tangential to the question, the JLayeredPane example cited by #camickr admits the following adaptation, which highlights the effect of mouseReleased() over an existing component.
public ChessBoard() {
...
// Add a few pieces to the board
addPiece(3, 0, "♛");
addPiece(4, 0, "♚");
addPiece(3, 7, "♕");
addPiece(4, 7, "♔");
}
static Font font = new Font("Sans", Font.PLAIN, 72);
private void addPiece(int col, int row, String glyph) {
JLabel piece = new JLabel(glyph, JLabel.CENTER);
piece.setFont(font);
JPanel panel = (JPanel) chessBoard.getComponent(col + row * 8);
panel.add(piece);
}
Besides the pointers to the LayerPane examples already provided, the issue with your original code centers around the setting of the preferred size of your label. You set it before the JLabel has been sized, so your:
l.setPreferredSize(l.getSize());
is ineffectual. If, on the other hand, you make that call after you make your call to setBounds, you will see your desired results. With that in mind, reorder this:
l.setPreferredSize(l.getSize());
l.setBounds(10, 10, 50, 20);
to look like this:
l.setBounds(10, 10, 50, 20);
l.setPreferredSize(l.getSize());
Since I had been following Romain Guy's blogs on Swing for a long time. I have a link that you might be interested in. He released the source - which used a GlassPane for DnD effects.
http://jroller.com/gfx/entry/drag_and_drop_effects_the
I myself never did use a fizzy animation/effect on DnD, so can't comment any further :-|