Why aren't my rectangles showing on JavaFX? - java

Trying out a simple game implementation
public class PlayerSprite extends Rectangle {
private String name;
private int playerID;
final int TILE = 32;
final int SIZE = 4;
public PlayerSprite(PlayerCharacter player, int id, Paint color) {
super(4, 4, color); //Currently a player takes up 4 points
this.name = player.getName();
this.playerID = id;
}
public int getPlayerSize() {
return SIZE;
}
}
My playerSprites are just rectangles that currently aren't showing. The PlayerSprite constructor is called from an object called LocationHome that extends Region.
public class LocationHome extends Region {
Image homeBGimage;
int lheight, lwidth;
public void LocationHome(Location location) {
this.setStyle("-fx-background-image: url(" + "'images/blackgrid.jpeg'" + ");" + "-fx-background-size: cover;");
lheight = location.getLocationHeight(); //Location method call
lwidth = location.getLocationWidth(); //Location method call
this.setPrefSize(lheight, lwidth);
}
public void placePlayer(PlayerCharacter player) {
//Create a PlayerSprite and position it as wanted
Image img = new Image("images/blackgrid.jpeg");
PlayerSprite playerSprite = new PlayerSprite(player, player.getID(), Color.AQUA);
this.layoutInArea(playerSprite, player.getPosition().getUL().getX(), player.getPosition().getUL().getY(), playerSprite.getPlayerSize(), playerSprite.getPlayerSize(), 0, HPos.CENTER, VPos.BASELINE);
this.getChildren().addAll(playerSprite);
}
}
And then, for my main JavaFX application...
Group rootPane = new Group();
World guiWorld = new WorldImpl(); //This is my game model
BorderPane locationPane = new BorderPane(); //locationPane designated for rendering a Location
guiCharacters = new HashMap<>();
int id=0;
for(PlayerCharacter each : guiWorld.getCharacters()) {
guiCharacters.put(id, each);
gridLocation.placePlayer(each);
id++;
}
locationPane.getChildren().addAll(gridLocation);
rootPane.getChildren().add(locationPane);
currScene = new Scene( rootPane, 1024, 1024 ); //Passing the rootPane/group to currScene
stage.setScene(currScene); //Make currScene contents visible
stage.setTitle("Spoon Game");
stage.show();

Related

3D Model does not show up in JavaFX

I'm trying to reproduce an example from this question, importing an STL file with InteractiveMesh. I've used as a model a calibration cube used in 3d printing.
This is my class code:
public class Example extends Application {
private Group root;
private PointLight pointLight;
private static final int VIEWPORT_SIZE_V1 = 720;
private static final double MODEL_SCALE_FACTOR = 400;
private static final double MODEL_X_OFFSET = 0; // standard
private static final double MODEL_Y_OFFSET = 0; // standard
private static final Color lightColor = Color.rgb(244, 255, 250);
private static final Color modelColor = Color.rgb(0, 190, 222);
private static final String MESH_FILENAME =
"/Users/user/Downloads/cube.stl";
static MeshView[] loadMeshViews(File file) {
StlMeshImporter importer = new StlMeshImporter();
try {
importer.read(file);
}
catch (ImportException e){
e.printStackTrace();
}
Mesh mesh = importer.getImport();
return new MeshView[] { new MeshView(mesh) };
}
private Group buildScene(MeshView[] meshViews) {
for (int i = 0; i < meshViews.length; i++) {
meshViews[i].setTranslateX(VIEWPORT_SIZE_V1 / 2 + MODEL_X_OFFSET);
meshViews[i].setTranslateY(VIEWPORT_SIZE_V1 / 2 + MODEL_Y_OFFSET);
meshViews[i].setTranslateZ(VIEWPORT_SIZE_V1 / 2);
meshViews[i].setScaleX(MODEL_SCALE_FACTOR);
meshViews[i].setScaleY(MODEL_SCALE_FACTOR);
meshViews[i].setScaleZ(MODEL_SCALE_FACTOR);
PhongMaterial sample = new PhongMaterial(modelColor);
sample.setSpecularColor(lightColor);
sample.setSpecularPower(16);
meshViews[i].setMaterial(sample);
meshViews[i].getTransforms().setAll(new Rotate(38, Rotate.Z_AXIS), new Rotate(20, Rotate.X_AXIS));
}
pointLight = new PointLight(lightColor);
pointLight.setTranslateX(VIEWPORT_SIZE_V1*3/4);
pointLight.setTranslateY(VIEWPORT_SIZE_V1/2);
pointLight.setTranslateZ(VIEWPORT_SIZE_V1/2);
PointLight pointLight2 = new PointLight(lightColor);
pointLight2.setTranslateX(VIEWPORT_SIZE_V1*1/4);
pointLight2.setTranslateY(VIEWPORT_SIZE_V1*3/4);
pointLight2.setTranslateZ(VIEWPORT_SIZE_V1*3/4);
PointLight pointLight3 = new PointLight(lightColor);
pointLight3.setTranslateX(VIEWPORT_SIZE_V1*5/8);
pointLight3.setTranslateY(VIEWPORT_SIZE_V1/2);
pointLight3.setTranslateZ(0);
Color ambientColor = Color.rgb(80, 80, 80, 0);
AmbientLight ambient = new AmbientLight(ambientColor);
root = new Group(meshViews);
root.getChildren().add(pointLight);
root.getChildren().add(pointLight2);
root.getChildren().add(pointLight3);
root.getChildren().add(ambient);
return root;
}
private PerspectiveCamera addCamera(Scene scene) {
PerspectiveCamera perspectiveCamera = new PerspectiveCamera();
System.out.println("Near Clip: " + perspectiveCamera.getNearClip());
System.out.println("Far Clip: " + perspectiveCamera.getFarClip());
System.out.println("FOV: " + perspectiveCamera.getFieldOfView());
scene.setCamera(perspectiveCamera);
return perspectiveCamera;
}
#Override
public void start(Stage stage) throws IOException {
File file = new File(MESH_FILENAME);
MeshView[] meshViews = loadMeshViews(file);
Group group = buildScene(meshViews);
group.setScaleX(2);
group.setScaleY(2);
group.setScaleZ(2);
group.setTranslateX(50);
group.setTranslateY(50);
Scene scene = new Scene(group, VIEWPORT_SIZE_V1, VIEWPORT_SIZE_V1,true);
scene.setFill(Color.rgb(10, 10, 40));
addCamera(scene);
stage.setScene(scene);
stage.setTitle("Example");
stage.show();
}
public static void main(String[] args) {
launch();
}
}
the result output of is:
I've followed each row of the example but something is wring. I've also tried to move the camera and change the scale...
Someone knows how can I fix it?
Thanks

JavaFX memory game (trouble hiding the values of the tiles)

I'm making a memory game for school and I'm having a bit of trouble hiding the tiles in my gridpane.
I've got a seperate class where I use my eventhandlers.
I used an ObservableList to fill in my gridpane with tiles but I got no idea how to make them disappear. Thanks for taking a look , I tried to use a FadeTransition in the view class.
View
public class GameView extends GridPane {
private static final int PAREN = 10;
private Label scoreSpeler1;
private Label countDown;
private Label title;
private final static Color backgroundColor = Color.rgb(225, 93, 68);
int waarde = 0;
ObservableList<Button> vakken;
public GameView() {
this.initialiseNodes();
this.layoutNodes();
this.verdwijnWaarde();
this.toonWaarde();
}
private void initialiseNodes() {
scoreSpeler1 = new Label("Score: 0");
countDown = new Label("Tijd: 60");
title = new Label("Memory");
/*knoppen met cijfers*/
vakken = FXCollections.observableArrayList(new ArrayList<>());
for (int i = 0; i < PAREN; i++) {
vakken.add(new Button(String.valueOf(waarde)));
vakken.add(new Button(String.valueOf(waarde)));
waarde++;
}
FXCollections.shuffle(vakken);
}
private void layoutNodes() {
//score en tijd plaatsen
this.add(scoreSpeler1, 0, 0);
this.add(title, 2, 0);
this.add(countDown, 4, 0);
//memory knoppen plaatsen
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
this.add(vakken.get(k), i, j + 2);
k++;
}
}
//label uiterlijk
GridPane.setHalignment(countDown, HPos.RIGHT);
GridPane.setHalignment(title, HPos.CENTER);
title.setId("titelGame");
scoreSpeler1.setId("scoreSpeler1");
countDown.setId("countDown");
//button/memory uiterlijk
for (Button button : vakken) {
button.setPrefHeight(120);
button.setPrefWidth(90);
}
//gridpane uiterlijk
this.setGridLinesVisible(false);
this.setBackground(new Background(new BackgroundFill(backgroundColor, null, null)));
this.setHgap(15);
this.setVgap(15);
this.setPadding(new Insets(10, 10, 10, 10));
this.autosize();
this.setAlignment(Pos.CENTER);
}
public void verdwijnWaarde() {
FadeTransition verstopWaardes = new FadeTransition();
verstopWaardes.durationProperty(Duration.seconds(2), this.vakken.get(1));
verstopWaardes.setToValue(0);
verstopWaardes.play();
}
public void toonWaarde() {
FadeTransition toonWaardes = new FadeTransition();
toonWaardes.durationProperty(Duration.seconds(0.5), vakken);
toonWaardes.setToValue(1);
toonWaardes.play();
}
}
presenter
public class GamePresenter {
private MemoryModel model;
private GameView gameView;
public GamePresenter(MemoryModel model, GameView gameView){
this.model = model;
this.gameView = gameView;
addEventHandlers();
}
private void addEventHandlers(){
gameView.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
gameView.toonWaarde();
}
});
}
private void updateView(){
}
public void addWindowEventHandlers(){
}
}

LibGDX: How to show/hide an overlay popup menu from the main game screen repetitively

I am doing a game called Fuego Peligro (based from another LibGDX "tutorial" project called Ninja Rabbit by nfantone, https://github.com/nfantone/ninja-rabbit) as my Thesis on my BIT course on my university, and I want an overlay menu of somesorts to show/hide over the main game screen.
The popup menu is like a checkpoint that displays a simple trivia-type minigame from the main platforming game. It is called through a Telegraph (handleMessage) method. The only problem is when the message is repeated and if the popup has been shown before, it does not want to re-show again.
All of the files and other details are here in this link: https://github.com/NinjaSiren/FuegoPeligro
All the .java files are here: https://github.com/NinjaSiren/FuegoPeligro/tree/master/core/src/com/mygdx/fuegopeligro
Here's the java class that calls all in-game overlay to render: LevelGraphicsProcessor.java
public class LevelGraphicsProcessor implements GraphicsProcessor, Telegraph {
private final LevelRenderer mapRenderer;
private final GameOverOverlay gameOver;
private final LevelEndOverlay levelEnd;
private MultipleChoice multipleChoice;
private FourPicsOneWord fourPicsOneWord;
private LetterPuzzle letterPuzzle;
private Wordscapes wordscapes;
private boolean renderGameOver;
private boolean renderLevelEnd;
private boolean minicamSelection;
private final CurrentPlayerStatus status;
private final NinjaRabbit ninja;
private final Entity entity;
public LevelGraphicsProcessor(final AssetManager assets, final LevelRenderer mapRenderer,
final FuegoPeligro game, final NinjaRabbit ninjaRabbit,
final CurrentPlayerStatus player) {
status = player;
ninja = ninjaRabbit;
if (ninjaRabbit == null) {
throw new IllegalArgumentException("'character' cannot be null"); }
this.entity = ninjaRabbit;
gameOver = new GameOverOverlay(game.getBatch(), assets, game);
levelEnd = new LevelEndOverlay(game.getBatch(), assets, game);
multipleChoice = new MultipleChoice(assets, game, ninjaRabbit);
fourPicsOneWord = new FourPicsOneWord(assets, game, ninjaRabbit);
letterPuzzle = new LetterPuzzle(assets, game, ninjaRabbit);
wordscapes = new Wordscapes(assets, game, ninjaRabbit);
this.mapRenderer = mapRenderer;
MessageManager.getInstance().addListeners(this, MessageType.GAME_OVER.code());
MessageManager.getInstance().addListeners(this, MessageType.FINISH_LEVEL.code());
MessageManager.getInstance().addListeners(this, MessageType.COLLECTED.code());
}
#Override
public void update(final Entity character, final Camera camera) {
mapRenderer.render((OrthographicCamera) camera);
}
/*
* (non-Javadoc)
*
* #see com.mygdx.fuegopeligro.graphics.GraphicsProcessor#draw(com.mygdx.fuegopeligro.entity.Entity,
* com.badlogic.gdx.graphics.g2d.Batch)
*/
#Override
public void draw(final Entity entity, final Batch batch) {
mapRenderer.update();
if (renderGameOver) {
gameOver.render(Gdx.graphics.getDeltaTime());
} else if (renderLevelEnd) {
levelEnd.render(Gdx.graphics.getDeltaTime());
} else if (minicamSelection) {
multipleChoice.render(Gdx.graphics.getDeltaTime());
wordscapes.render(Gdx.graphics.getDeltaTime());
letterPuzzle.render(Gdx.graphics.getDeltaTime());
fourPicsOneWord.render(Gdx.graphics.getDeltaTime());
entity.changeState(NinjaRabbitState.IDLE);
byte worldValue = status.getCurrentWorld();
//short levelValue = status.getCurrentLevel();
short mgValue = status.getMGValue();
if (worldValue == 1) {
//short easyValue = status.getEqaValue();
if (mgValue == 1) {
multipleChoice.setVisible(true);
Gdx.input.setInputProcessor(multipleChoice.stage);
if (multipleChoice.enterAnswer.isPressed()) {
multipleChoice.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 2) {
wordscapes.setVisible(true);
Gdx.input.setInputProcessor(wordscapes.stage);
if (wordscapes.enterAnswer.isPressed()) {
wordscapes.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 3) {
letterPuzzle.setVisible(true);
Gdx.input.setInputProcessor(letterPuzzle.stage);
if (letterPuzzle.enterAnswer.isPressed()) {
letterPuzzle.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 4) {
fourPicsOneWord.setVisible(true);
Gdx.input.setInputProcessor(fourPicsOneWord.stage);
if (fourPicsOneWord.enterAnswer.isPressed()) {
fourPicsOneWord.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
}
} else if (worldValue == 2) {
//short hardValue = status.getHqaValue();
if (mgValue == 1) {
multipleChoice.setVisible(true);
Gdx.input.setInputProcessor(multipleChoice.stage);
if (multipleChoice.enterAnswer.isPressed()) {
multipleChoice.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 2) {
wordscapes.setVisible(true);
Gdx.input.setInputProcessor(wordscapes.stage);
if (wordscapes.enterAnswer.isPressed()) {
wordscapes.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 3) {
letterPuzzle.setVisible(true);
Gdx.input.setInputProcessor(letterPuzzle.stage);
if (letterPuzzle.enterAnswer.isPressed()) {
letterPuzzle.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
} else if (mgValue == 4) {
fourPicsOneWord.setVisible(true);
Gdx.input.setInputProcessor(fourPicsOneWord.stage);
if (fourPicsOneWord.enterAnswer.isPressed()) {
fourPicsOneWord.setVisible(false);
Gdx.input.setInputProcessor(new NinjaRabbitInputProcessor(ninja));
}
}
}
}
}
#Override
public boolean handleMessage(final Telegram msg) {
renderGameOver = msg.message == MessageType.GAME_OVER.code();
renderLevelEnd = msg.message == MessageType.FINISH_LEVEL.code();
minicamSelection = msg.message == MessageType.COLLECTED.code();
return true;
}
#Override
public void resize(final int width, final int height) {
gameOver.resize(width, height);
levelEnd.resize(width, height);
multipleChoice.resize(width, height);
wordscapes.resize(width, height);
letterPuzzle.resize(width, height);
fourPicsOneWord.resize(width, height);
}
#Override
public void dispose() {
gameOver.dispose();
levelEnd.dispose();
multipleChoice.dispose();
wordscapes.dispose();
letterPuzzle.dispose();
fourPicsOneWord.dispose();
}
}
Here is one of the popup minigame I want to show when a the Message is received, and hidden when a button is clicked.: MultipleChoice.java
public class MultipleChoice implements Disposable {
private static final String QUESTION_LABEL = "CHECKPOINT: MULTIPLE CHOICE";
private static final String ENTER_ANSWER = "ENTER";
private static final String HINT_ANSWER = "HINT";
public final Stage stage;
private final NinjaRabbit ninja;
private final Label QuestionLabel;
private final Label QuestionText;
private final TextButton answer1;
private final TextButton answer2;
private final TextButton answer3;
private final TextButton answer4;
public final TextButton enterAnswer;
private final TextButton enterHints;
private final Table table;
public MultipleChoice(final AssetManager assets, final FuegoPeligro game,
final NinjaRabbit ninjaRabbit) {
stage = new Stage(new ScreenViewport(), game.getBatch());
ninja = ninjaRabbit;
Label.LabelStyle style = new Label.LabelStyle();
AssetManager assetManager = new AssetManager();
assetManager.load(Assets.GAME_UI_SKIN);
assetManager.finishLoading();
Skin skin = assetManager.get(Assets.GAME_UI_SKIN);
style.fontColor = Color.WHITE;
style.font = assets.get(Assets.HUD_FONT);
QuestionLabel = new Label(QUESTION_LABEL, style);
style.fontColor = Color.WHITE;
style.font = assets.get(Assets.HUD_FONT);
QuestionText = new Label("", style);
answer1 = new TextButton("", skin);
answer1.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
answer2 = new TextButton("", skin);
answer2.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
answer3 = new TextButton("", skin);
answer3.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
answer4 = new TextButton("", skin);
answer4.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
// enter answer
enterAnswer = new TextButton(ENTER_ANSWER, skin);
enterAnswer.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
// enter hints
enterHints = new TextButton(HINT_ANSWER, skin);
enterHints.addListener(new ClickListener() {
#Override
public void clicked(final InputEvent event, final float x, final float y) {
}
});
table = new Table();
table.setFillParent(true);
table.setDebug(true);
table.add(QuestionLabel).expand(true, false).center();
table.row().pad(20, 0, 0, 10);
table.add(QuestionText).expand(true, false);
table.row().pad(10, 0, 0, 20);
table.add(answer1).expand(true, false);
table.add(answer2).expand(true, false);
table.row().pad(10, 0, 0, 20);
table.add(answer3).expand(true, false);
table.add(answer4).expand(true, false);
table.row().pad(10, 0, 0, 20);
table.add(enterAnswer).expand(true, false);
table.add(enterHints).expand(true, false);
table.setVisible(false);
stage.addActor(table);
stage.setKeyboardFocus(table);
}
public void render(final float delta) {
Gdx.gl20.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl20.glDisable(GL20.GL_BLEND);
stage.getBatch().end();
stage.act(delta);
stage.draw();
stage.getBatch().begin();
}
public void resize(final int width, final int height) { stage.getViewport().update(width, height); }
#Override
public void dispose() {
stage.dispose();
}
public void setVisible(boolean value) {
table.setVisible(value);
}
}
When using LibGDX, the standard convention for UI is to use Scene2D, and Scene2D objects must be contained within a Stage - to use a window like overlay, one can use the special Table derivative: the Window class.
Any Actors you wish to be in the overlay can be added to the Window instance and positioned within just like its own Stage or Table, and the Window can be added to the scene and removed from the scene - even faded in and out using the fade(In/Out) actions (instead of directly adding and removing as is done in the following example):
public class ExampleClass {
...
private Stage stage = new Stage(...);
private Window popUp = new Window("...");
private TextButton windowButton1 = ..., windowButton2 = ...;
...
public ExampleClass() {
...
Gdx.setInputProcessor(stage); //Allows input to Scene2D components - important!
//Register click listeners to buttons to close window when clicked
windowButton1.addListener(new CloseButtonListener(this));
windowButton2.addListener(new CloseButtonListener(this));
...
//Add buttons to window
popUp.add(windowButton1);
popUp.add(windowButton2);
...
}
//Run when message is received
public void messageReceived() {
...
stage.add(popUp); //Add window to stage you want to overlay
...
}
...
public Stage getStage() {
return stage;
}
public Window getPopUp() {
return popUp;
}
...
}
class CloseButtonListener implements ClickListener { //Inner class for handling button clicks, multiple can be created for different button types with different logic when window is closed.
private ExampleClass exampleInstance;
public CloseButtonListener(ExampleClass exampleInstance) {
this.exampleInstance = exampleInstance;
}
//Remove the window from the stage when the button is clicked, handles any other logic too depending on button.
#Override
public void clicked(InputEvent event, float x, float y) {
...
exampleInstance.addAction(Actions.removeActor());
...
}
}

Add MouseListener with reference to other class

I want to add MouseListener to a class which extends JPanel. The Listener references to another class where the JPanel itself is created and added to contentPane. By pressing the mouse on JPanel, it should be removed. It is working well but I cannot call repaint() because my removing methode is static. How I can solve this?
This is the extended class:
public class PanelDraggable extends JPanel {
public PanelDraggable () {
.
.
.
MouseInputAdapter closeMouseAdapter = new CloseMouseHandler();
addMouseListener(closeMouseAdapter);
}
private class CloseMouseHandler extends MouseInputAdapter {
public void mouseClicked(MouseEvent e) {
TblManagement.RemoveTable();
}
}
}
And in this class I want to create the panel and remove it:
public void AddTables() {
String dbShortName = combo.getSelectedItem().toString();
String dbName = prop.get(dbNamesFile, dbShortName);
int x = 50; int y = 150; int width = 150; int height = 220; //set Size and location
int [] indices = tblList.getSelectedIndices();
panel = new PanelDraggable [indices.length];
for (int i = 0; i < indices.length ; i++) {
String tblName = tblList.getModel().getElementAt(i).toString();
String sql = "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "+
"`TABLE_SCHEMA`='"+dbName+"' AND `TABLE_NAME`='"+tblName+"'";
JList<?> columnslist = new JList<String>();
columnslist.setModel(getListModel(dbName, sql, 1));
JScrollPane sc = new JScrollPane(columnslist);
panel[i] = new PanelDraggable(x, y , width, height, tblName, sc);
MouseInputAdapter mousehandler = new TableMouseHandler();
panel[i].addMouseListener(mousehandler);
mainPanel.add(panel[i]);
x+=15;
y+=20;
}
revalidate();
repaint();
}
private class TableMouseHandler extends MouseInputAdapter {
public void mouseEntered(MouseEvent e) {
removeComp = (JComponent) e.getComponent();
}
}
public static void RemoveTable() {
mainPanel.remove(removeComp);
}
Thank you for help.
You need to take in an instance of the TableManagement class as an argument for each panel, that way you don't have to do it in the static context. Also, I removed the unnecessary sub-classes for your mouseAdapters you were creating and created them in the more accepted way.
public class PanelDraggable extends JPanel {
public PanelDraggable (..., final TableManagement tblManagement) {
.
.
.
addMouseListener(new MouseAdapter() {
#Override
public void (MouseEvent e) {
tblManagement.removeTable();
}
});
}
}
Then in your TableManagement Class
public void AddTables() {
String dbShortName = combo.getSelectedItem().toString();
String dbName = prop.get(dbNamesFile, dbShortName);
int x = 50; int y = 150; int width = 150; int height = 220; //set Size and location
int [] indices = tblList.getSelectedIndices();
panel = new PanelDraggable [indices.length];
for (int i = 0; i < indices.length ; i++) {
String tblName = tblList.getModel().getElementAt(i).toString();
String sql = "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE "+
"`TABLE_SCHEMA`='"+dbName+"' AND `TABLE_NAME`='"+tblName+"'";
JList<?> columnslist = new JList<String>();
columnslist.setModel(getListModel(dbName, sql, 1));
JScrollPane sc = new JScrollPane(columnslist);
// There is an extra argument here. Whatever your
// mainPanel used to be in the static method
panel[i] = new PanelDraggable(x, y , width, height, tblName, sc, mainPanel);
panel[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered() {
removeComp = (JComponent) e.getComponent();
}
});
mainPanel.add(panel[i]);
x+=15;
y+=20;
}
revalidate();
repaint();
}
public void RemoveTable() {
this.remove(removeComp);
}
Side-Note: You should look into Java naming conventions. Only classes have their first character capitalized.

Swing Timers and Animations in JPanel

Im trying to animate 2 boxes to go from the top right to the bottom left of a JPanel. For the animation I'm using a Swing Timer and SwingUtilities.invokeLater(). The problem is that when I click the start button. It only animates and moves the blue box, but not the red one.
Heres the code:
//import neccessary stuff
public class Example extends JFrame {
public static void main(String[] args) {
Example e = new Example();
e.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
e.setSize(600, 565);
e.setVisible(true);
}</code>
private JButton startButton = new JButton("Start");
private JPanel theTable = new table();
public Example() {
add(startButton, BorderLayout.SOUTH);
add(theTable, BorderLayout.CENTER);
Handler handler = new Handler();
startButton.addActionListener(handler);
}
public ArrayList<Integer> xPos, yPos;
final int START_POSITION_X = 470;
final int START_POSITION_Y = 10;
final int[] END_POSITION_X = {70, 87};
final int END_POSITION_Y = 160;
private class table extends JPanel {
public table() {
xPos = new ArrayList<Integer>();
yPos = new ArrayList<Integer>();
xPos.add(START_POSITION_X); //default position for box1
yPos.add(START_POSITION_Y);
xPos.add(START_POSITION_X); //default position for box2
yPos.add(START_POSITION_Y);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(new Color(-16756217));
g.setColor(Color.RED);
g.fillRect(xPos.get(1), yPos.get(1), 89, 129);
g.setColor(Color.BLUE);
g.fillRect(xPos.get(0), yPos.get(0), 89, 129);
if (isAnimating) {
animator.start();
} else {
animator.stop();
isAnimating = false;
}
}
}
private class Handler implements ActionListener {
public void actionPerformed(ActionEvent e) {
Runnable r1 = new Runnable() {
#Override
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}
};
SwingUtilities.invokeLater(r1);
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
}
}
public void animateCard(int card, int xDest, int yDest) {
cardID = card;
xDestination = xDest;
yDestination = yDest;
totalXDistance = Math.abs(xDestination - START_POSITION_X);
totalYDistance = Math.abs(yDestination - START_POSITION_Y);
animator.start();
}
int cardID;
int xDestination, yDestination, totalXDistance, totalYDistance;
boolean isAnimating = false;
Timer animator = new Timer(15, new ActionListener() {
int startVel = 20;
public void actionPerformed(ActionEvent e) {
double xRelDistance, xAbsDistance, xVel;
int xRealVel;
xAbsDistance = xDestination - xPos.get(cardID);
xRelDistance = xAbsDistance / totalXDistance;
xVel = startVel * xRelDistance;
double yRelDistance, yAbsDistance, yVel;
yAbsDistance = yDestination - yPos.get(cardID);
yRelDistance = yAbsDistance / totalYDistance;
yVel = startVel * yRelDistance;
if (xVel > 0) {
xRealVel = (int) java.lang.Math.ceil(xVel);
} else {
xRealVel = (int) java.lang.Math.floor(xVel);
}
xPos.set(cardID, xPos.get(cardID) + xRealVel);
int yRealVel;
if (xVel > 0) {
yRealVel = (int) java.lang.Math.ceil(yVel);
yPos.set(cardID, yPos.get(cardID) + yRealVel);
} else {
yRealVel = (int) java.lang.Math.floor(yVel);
}
yPos.set(cardID, yPos.get(cardID) + yRealVel);
if ((xPos.get(cardID) == xDestination) && (yPos.get(cardID) == yDestination)) {
isAnimating = false;
} else {
isAnimating = true;
}
repaint();
}
});
}
So all of those variable declared at the class level are shared... Your first call to animateCard will set them and then your second call to animateCard is going to completely overwrite the previous values. You need to change them from class variables to parameters of the animation.
Create a new class AnimationTask that implements ActionListener and save the variables in that class.
E.g.,
class AnimationTask implements ActionListener {
private int cardID;
private int xDest;
private int yDest;
private int totalXDistance;
private int totalYDistance;
public AnimationTask(int cardID, int xDest, int yDest) {
this.cardID = cardID;
this.xDest = xDest;
this.yDest = yDest;
this.totalXDistance = Math.abs(xDestination - START_POSITION_X);
this.totalYDistance = Math.abs(yDestination - START_POSITION_Y);
}
public void actionPerformed(ActionEvent e) {
// do your animation logic...
}
}
and use that custom class in your "animator"
E.g.,
Timer animator = new Timer(15, new AnimationTask(cardId, xDest, yDest);
put
animateCard(1, END_POSITION_X[1], END_POSITION_Y);
inside your run method:
public void run() {
animateCard(0, END_POSITION_X[0], END_POSITION_Y);
}

Categories