I am using a BufferedImage to display two images on my JPanel. However, I want the images move in random directions when a button is clicked and should only stop when another button is pressed.
How do I make my images move randomly on the panel?
This is part of my code:
private void getImages() {
try {
frogImage = ImageIO.read(new File ("C:\\OOP\\CyberPet\\src\\img\\frog.gif"));
flyImage = ImageIO.read(new File ("C:\\OOP\\CyberPet\\src\\img\\fly.gif"));
g = panel.getGraphics();
g.drawImage(frogImage, 500, 25, 40, 40, null); //set position and size of the image
g.drawImage(flyImage, 40, 40, 10, 10, null); //set position and size of the image
} catch (IOException e) {
}
}
public void actionPerformed(ActionEvent event) {
getImages();
if (event.getSource() == makeButton){
responseArea.setText(enterField.getText());
}
else if(event.getSource() == hungryButton){
}
else if(event.getSource() == resetButton){
}
}
public void draw()
{
}
}
You can always check this example for inspiration.
Basically, it uses a javax.swing.Timer to pace the animation. Whenever an animal reaches an edge of the frame, it will reverse its direction to go in reverse. The directions and speed are randomly computed, adjust these to your needs:
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UnsupportedLookAndFeelException;
public class TestAnimationFlyAndFrog {
private static final int NB_OF_IMAGES_PER_SECOND = 50;
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private Random random = new Random();
private double dxFrog;
private double dyFrog;
private double xFrog = WIDTH / 2;
private double yFrog = HEIGHT / 2;
private double dxFly;
private double dyFly;
private double xFly = WIDTH / 2;
private double yFly = HEIGHT / 2;
protected void initUI() throws MalformedURLException {
final JFrame frame = new JFrame(TestAnimationFlyAndFrog.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
final JLabel frog = new JLabel(new ImageIcon(new URL("http://www.iconshock.com/img_jpg/SUPERVISTA/animals/jpg/128/frog_icon.jpg")));
frog.setSize(frog.getPreferredSize());
final JLabel fly = new JLabel(new ImageIcon(new URL("http://www.iconshock.com/img_jpg/SUPERVISTA/animals/jpg/128/fly_icon.jpg")));
fly.setSize(fly.getPreferredSize());
frame.setMinimumSize(new Rectangle(frog.getPreferredSize()).union(new Rectangle(fly.getPreferredSize())).getSize());
frame.add(frog);
frame.add(fly);
frame.setSize(WIDTH, HEIGHT);
dxFrog = getNextSpeed() * (random.nextBoolean() ? 1 : -1);
dyFrog = getNextSpeed() * (random.nextBoolean() ? 1 : -1);
dxFly = getNextSpeed() * (random.nextBoolean() ? 1 : -1);
dyFly = getNextSpeed() * (random.nextBoolean() ? 1 : -1);
Timer t = new Timer(1000 / NB_OF_IMAGES_PER_SECOND, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
xFrog += dxFrog;
yFrog += dyFrog;
if (xFrog + frog.getWidth() > frame.getContentPane().getWidth()) {
xFrog = frame.getContentPane().getWidth() - frog.getWidth();
dxFrog = -getNextSpeed();
} else if (xFrog < 0) {
xFrog = 0;
dxFrog = getNextSpeed();
}
if (yFrog + frog.getHeight() > frame.getContentPane().getHeight()) {
yFrog = frame.getContentPane().getHeight() - frog.getHeight();
dyFrog = -getNextSpeed();
} else if (yFrog < 0) {
yFrog = 0;
dyFrog = getNextSpeed();
}
frog.setLocation((int) xFrog, (int) yFrog);
xFly += dxFly;
yFly += dyFly;
if (xFly + fly.getWidth() > frame.getContentPane().getWidth()) {
xFly = frame.getContentPane().getWidth() - fly.getWidth();
dxFly = -getNextSpeed();
} else if (xFly < 0) {
xFly = 0;
dxFly = getNextSpeed();
}
if (yFly + fly.getHeight() > frame.getContentPane().getHeight()) {
yFly = frame.getContentPane().getHeight() - fly.getHeight();
dyFly = -getNextSpeed();
} else if (yFly < 0) {
yFly = 0;
dyFly = getNextSpeed();
}
fly.setLocation((int) xFly, (int) yFly);
}
});
frame.setVisible(true);
t.start();
}
private double getNextSpeed() {
return 2 * Math.PI * (0.5 + random.nextDouble());
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new TestAnimationFlyAndFrog().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Related
This game is connect four and at the end of the game I give the player an option
to play again. So if they want to play again I try clearing the canvas and resetting the board. I know basically nothing about doing java graphics so I'm
pretty certain the error stems from me not understanding something about the
graphics as opposed to the games logic.
If you look at the update gameState method right after I get input from the user
is when I try to reset everything. And when I say reset I mean remove all images and such from window. Instead of everything being removed it just locks up.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
public class MainFrame extends JFrame
{
public static final String GAME_NAME = "Connect Four!";
private static final int _PLAYER_ONE_TURN = 1;
private static String _title;
private Board _gameBoard;
private ToolBar _buttons;
private boolean _humanVsHuman;
private int _gameIteration;
public MainFrame()
{
super();
final String INITIAL_GAME_MESSAGE = "Human Vs. Human? Default Computer "
+ "Vs. Human.";
final String MENU_TITLE = "Game Setup...";
final String[] MENU_OPTIONS = { "Yes!", "No!" };
_gameBoard = new Board(Game.BOARD_WIDTH, Game.BOARD_HEIGHT);
_buttons = new ToolBar(Game.BOARD_WIDTH);
_humanVsHuman = 0 == JOptionPane.showOptionDialog(this,
INITIAL_GAME_MESSAGE, MENU_TITLE, JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, MENU_OPTIONS, MENU_OPTIONS[1]);
updateTitle();
setLayout(new BorderLayout());
setSize(Game.SCREEN_WIDTH, Game.SCREEN_HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(_buttons, BorderLayout.SOUTH);
setVisible(true);
}
public void paint(Graphics g)
{
GamePiece[][] board = _gameBoard.getBoard();
_buttons.repaint();
for (int x = 0; x < Game.BOARD_WIDTH; x++)
{
for (int y = 0; y < Game.BOARD_HEIGHT; y++)
{
if (board[x][y] != null)
{
g.setColor(
board[x][y].toString().equals(GamePiece.GAME_PIECE_BLUE)
? Color.BLUE : Color.RED);
g.fillOval((int) (x * (GamePiece.SIZE[0] * .92) + ((Game.SCREEN_WIDTH - (GamePiece.SIZE[0] * Game.BOARD_WIDTH)) / Game.BOARD_WIDTH) * x + 30), (int) (y * (GamePiece.SIZE[1] * .9) + ((Game.SCREEN_HEIGHT - (GamePiece.SIZE[1] * Game.BOARD_HEIGHT)) / Game.BOARD_HEIGHT) * y + 30),
GamePiece.SIZE[0], GamePiece.SIZE[1]);
}
}
}
}
public void updateTitle()
{
final String HUMAN = "HUMAN";
final String COMPUTER = "COMPUTER";
final String PLAYER = "PLAYER";
final String TURN = "TURN";
_title = GAME_NAME + " " + Game.VERSION + ": " + PLAYER + " "
+ (getPlayerTurn(_gameIteration) == _PLAYER_ONE_TURN
? _humanVsHuman ? "1" : HUMAN
: _humanVsHuman ? "2" : COMPUTER)
+ " " + TURN;
setTitle(_title);
}
public void updateGameState(boolean aWinner)
{
final String AGAIN = "Play Again?";
final String ROUND_OVER = "ROUND OVER";
final String[] OPTIONS = { "Yes", "No" };
boolean hasWinner = aWinner;
if (hasWinner || _gameBoard.isFull())
{
if (hasWinner)
{
JOptionPane.showMessageDialog(this,
getPlayerTurn(_gameIteration) == _PLAYER_ONE_TURN
? "Blue won!" : "Red won!");
}
if (0 != JOptionPane.showOptionDialog(this, AGAIN, ROUND_OVER,
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
OPTIONS, OPTIONS[1]))
{
setVisible(false);
dispose();
}
else
{
_gameBoard.clearBoard();
removeAll();//or remove(JComponent)
invalidate();
_buttons = new ToolBar(Game.BOARD_WIDTH);
updateMainFrame();
}
}
_gameIteration++;
}
public void updateMainFrame()
{
revalidate();
repaint();
updateTitle();
if (_gameIteration + 1 == Integer.MAX_VALUE)
{
if (getPlayerTurn(_gameIteration) == _PLAYER_ONE_TURN)
{
_gameIteration = 0;
}
else
{
_gameIteration = 1;
}
}
}
private int getPlayerTurn(int iteration)
{
return (iteration % 2) + 1;
}
private class ToolBar extends JPanel
{
public ToolBar(int numberOfButtons)
{
setLayout(new FlowLayout(FlowLayout.CENTER,
(int) (Game.SCREEN_WIDTH / numberOfButtons) / 2, 0));
for (int i = 0; i < numberOfButtons; i++)
{
JButton button = new JButton("" + (i + 1));
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
boolean hasWinner;
if (!_gameBoard
.isRowFull(Integer.parseInt(button.getText()) - 1))
{
hasWinner = _gameBoard.insert(
getPlayerTurn(_gameIteration) == _PLAYER_ONE_TURN
? new BluePiece() : new RedPiece(),
Integer.parseInt(button.getText()) - 1);
updateMainFrame();
updateGameState(hasWinner);
}
}
});
add(button);
}
}
}
}
Here is my code. I want to know which l was clicked and then in a new frame, display that ImageIcon.
The e.getSource() is not working...
final JFrame shirts = new JFrame("T-shirts");
JPanel panel = new JPanel(new GridLayout(4, 4, 3, 3));
for (int i = 1; i < 13; i++) {
l = new JLabel(new ImageIcon("T-shirts/"+i+".jpg"), JLabel.CENTER);
l.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
l.setFont(l.getFont().deriveFont(20f));
panel.add(l);
}//end of for loop
panel.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
sizes = new JFrame("Shopping");
sizes.setVisible(true);
sizes.setSize(500, 500);
sizes.setLocation(100,200);
shirts.dispose();
if(e.getSource()==l){//FIX
sizes.add(l);
}//end of if
}
});
shirts.setContentPane(panel);
shirts.setSize(1000, 1000);
shirts.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
shirts.setVisible(true);
If you add your MouseListener directly to your JLabels, then you can display the pressed label's icon easily in a JOptionPane:
#Override
public void mousePressed(MouseEvent mEvt) {
JLabel label = (JLabel) mEvt.getSource();
Icon icon = label.getIcon();
JOptionPane.showMessageDialog(label, icon);
}
For example:
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
public class FooMouseListener extends JPanel {
private GetImages getImages;
public FooMouseListener() throws IOException {
getImages = new GetImages();
setLayout(new GridLayout(GetImages.SPRITE_ROWS, GetImages.SPRITE_COLS));
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
for (int i = 0; i < GetImages.SPRITE_CELLS; i++) {
JLabel label = new JLabel(getImages.getIcon(i));
add(label);
label.addMouseListener(myMouseAdapter);
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getSource();
Icon icon = label.getIcon();
JOptionPane.showMessageDialog(label, icon, "Selected Icon", JOptionPane.PLAIN_MESSAGE);
}
}
private static void createAndShowGui() {
FooMouseListener mainPanel = null;
try {
mainPanel = new FooMouseListener();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("FooMouseListener");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class GetImages {
private static final String SPRITE_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2011/169/0/8/blue_player_sprite_sheet_by_resetado-d3j7zba.png";
public static final int SPRITE_ROWS = 6;
public static final int SPRITE_COLS = 6;
public static final int SPRITE_CELLS = SPRITE_COLS * SPRITE_ROWS;
private List<Icon> iconList = new ArrayList<>();
public GetImages() throws IOException {
URL imgUrl = new URL(SPRITE_PATH);
BufferedImage mainImage = ImageIO.read(imgUrl);
for (int i = 0; i < SPRITE_CELLS; i++) {
int row = i / SPRITE_COLS;
int col = i % SPRITE_COLS;
int x = (int) (((double) mainImage.getWidth() * col) / SPRITE_COLS);
int y = (int) ((double) (mainImage.getHeight() * row) / SPRITE_ROWS);
int w = (int) ((double) mainImage.getWidth() / SPRITE_COLS);
int h = (int) ((double) mainImage.getHeight() / SPRITE_ROWS);
BufferedImage img = mainImage.getSubimage(x, y, w, h);
ImageIcon icon = new ImageIcon(img);
iconList.add(icon);
}
}
// get the Icon from the List at index position
public Icon getIcon(int index) {
if (index < 0 || index >= iconList.size()) {
throw new ArrayIndexOutOfBoundsException(index);
}
return iconList.get(index);
}
public int getIconListSize() {
return iconList.size();
}
}
Have you tried this?
public void mouseClicked(MouseEvent e)
{
sizes = new JFrame("Shopping");
sizes.add(l);
sizes.setVisible(true);
sizes.setSize(500, 500);
sizes.setLocation(100,200);
shirts.dispose();
//Remove the "e.getSource()" part.
}
It will automatically display the image, because you are assigning the Image Name to it, in the same segment as the Addition to the new JFrame.
Let me know of the outcome
Am trying to modify a java code that implements Analog Clock using BufferedImage. I want the face of the clock to be changed dynamically when a user clicks on a button that scrolls through an array preloaded with the locations of images. So far my attempts have failed. I have two classes; The first Class creates and displays the Analog, and the second class attempts to change the face of the Analog clock using a mutator (setAnalogClockFace()) and an accessor (getAnalogClockFace()). The following is the code for the first Class as found on here, with minor modifications:
package panels;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.util.*;
public class Clock extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private int hours = 0;
private int minutes = 0;
private int seconds = 0;
private int millis = 0;
private static final int spacing = 10;
private static final float threePi = (float)(3.0 * Math.PI);
private static final float radPerSecMin = (float)(Math.PI/30.0);
private int size; //height and width of clockface
private int centerX;//X coord of middle of clock
private int centerY;//Y coord of middle of clock
private BufferedImage clockImage;
private BufferedImage imageToUse;
private javax.swing.Timer t;
public Clock(){
this.setPreferredSize(new Dimension(203,203));
this.setBackground(getBackground());
this.setForeground(Color.darkGray);
t = new javax.swing.Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent ae){
update();
}
});
}
public void update(){
this.repaint();
}
public void start(){
t.start();
}
public void stop(){
t.stop();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
size = ((w < h) ? w : h) - 2 * spacing;
centerX = size/2 + spacing;
centerY = size/2 + spacing;
setClockFace(new AnalogClockTimer().getAnalogClockFace());
clockImage = getClockFace();
if (clockImage == null | clockImage.getWidth() != w | clockImage.getHeight() != h){
clockImage = (BufferedImage)(this.createImage(w,h));
Graphics2D gc = clockImage.createGraphics();
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawClockFace(gc);
}
Calendar now = Calendar.getInstance();
hours = now.get(Calendar.HOUR);
minutes = now.get(Calendar.MINUTE);
seconds = now.get(Calendar.SECOND);
millis = now.get(Calendar.MILLISECOND);
g2d.drawImage(clockImage, null, 0, 0);
drawClockHands(g);
}
private void drawClockHands(Graphics g){
int secondRadius = size/2;
int minuteRadius = secondRadius * 3/4;
int hourRadius = secondRadius/2;
float fseconds = seconds + (float)millis/1000;
float secondAngle = threePi - (radPerSecMin * fseconds);
drawRadius(g, centerX, centerY, secondAngle, 0, secondRadius);
float fminutes = (float)(minutes + fseconds/60.0);
float minuteAngle = threePi - (radPerSecMin * fminutes);
drawRadius(g, centerX, centerY, minuteAngle, 0 , minuteRadius);
float fhours = (float)(hours + fminutes/60.0);
float hourAngle = threePi - (5 * radPerSecMin * fhours);
drawRadius(g, centerX, centerY, hourAngle, 0 ,hourRadius);
}
private void drawClockFace(Graphics g){
//g.setColor(Color.lightGray);
g.fillOval(spacing, spacing, size, size);
//g.setColor(new Color(168,168,168));
g.drawOval(spacing, spacing, size, size);
for(int sec = 0; sec < 60; sec++){
int tickStart;
if(sec%5 == 0){
tickStart = size/2-10;
}else{
tickStart = size/2-5;
}
drawRadius(g, centerX, centerY, radPerSecMin * sec, tickStart, size/2);
}
}
private void drawRadius(Graphics g, int x, int y, double angle,
int minRadius, int maxRadius){
float sine = (float)Math.sin(angle);
float cosine = (float)Math.cos(angle);
int dxmin = (int)(minRadius * sine);
int dymin = (int)(minRadius * cosine);
int dxmax = (int)(maxRadius * sine);
int dymax = (int)(maxRadius * cosine);
g.drawLine(x+dxmin, y+dymin, x+dxmax,y+dymax);
}
public void setClockFace(BufferedImage img){
if(img != null){
imageToUse = img;
}else{
try{
imageToUse =
ImageIO.read(getClass().getClassLoader().getResource("http://imgur.com/T8x0I29"));
}catch(IOException io){
io.printStackTrace();
}
}
}
public BufferedImage getClockFace(){
return imageToUse;
}
}
The second Class that attempts to set the Clock face is:
package panels;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import panels.Clock;
public class AnalogClockTimer extends javax.swing.JPanel implements ActionListener,
MouseListener {
private Clock clock;
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton prevBtn;
private JTextField clockFaceCount;
private JButton nextBtn;
private JPanel buttonedPanel,leftPanel,rightPanel;
private BufferedImage image;
String[] clockFace;
int arrayPointer = 1;
/**
* Auto-generated main method to display this
* JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new AnalogClockTimer());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public AnalogClockTimer() {
super();
initGUI();
}
private void initGUI() {
try {
BorderLayout thisLayout = new BorderLayout();
this.setLayout(thisLayout);
this.setPreferredSize(new java.awt.Dimension(283, 233));
this.setBackground(getBackground());
{
clock = new Clock();
add(clock,BorderLayout.CENTER);
clock.start();
clock.setSize(203, 203);
}
{
buttonedPanel = new JPanel();
FlowLayout buttonedPanelLayout = new FlowLayout();
buttonedPanel.setLayout(buttonedPanelLayout);
this.add(buttonedPanel, BorderLayout.SOUTH);
buttonedPanel.setPreferredSize(new java.awt.Dimension(283, 30));
{
prevBtn = new JButton(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_rest.png")));
prevBtn.setPreferredSize(new java.awt.Dimension(20, 19));
prevBtn.setBackground(getBackground());
prevBtn.setBorderPainted(false);
prevBtn.setEnabled(false);
prevBtn.addMouseListener(this);
prevBtn.addActionListener(this);
buttonedPanel.add(prevBtn);
}
{
nextBtn = new JButton(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_rest.png")));
nextBtn.setPreferredSize(new java.awt.Dimension(20, 19));
nextBtn.setBackground(getBackground());
nextBtn.setBorderPainted(false);
nextBtn.addMouseListener(this);
nextBtn.addActionListener(this);
}
{
clockFaceCount = new JTextField();
clockFaceCount.setPreferredSize(new java.awt.Dimension(50, 19));
clockFaceCount.setBackground(getBackground());
clockFaceCount.setBorder(null);
clockFaceCount.setHorizontalAlignment(SwingConstants.CENTER);
clockFaceCount.setEditable(false);
buttonedPanel.add(clockFaceCount);
buttonedPanel.add(nextBtn);
}
{
clockFace = new String[]{"http://imgur.com/079QSdJ","http://imgur.com/vQ7tZjI",
"http://imgur.com/T8x0I29"};
for(int i = 1; i <= clockFace.length; i++){
if(i == 1){
nextBtn.setEnabled(true);
prevBtn.setEnabled(false);
}
clockFaceCount.setText(arrayPointer+" of "+clockFace.length);
}
}
{
leftPanel = new JPanel();
leftPanel.setPreferredSize(new Dimension(40, getHeight()));
add(leftPanel,BorderLayout.WEST);
}
{
rightPanel = new JPanel();
rightPanel.setPreferredSize(new Dimension(40,getHeight()));
add(rightPanel,BorderLayout.EAST);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void mouseClicked(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_pressed.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_pressed.png")));
}
#Override
public void mouseEntered(MouseEvent me) {
if(me.getSource()==prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_hover.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_hover.png")));
}
#Override
public void mouseExited(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_rest.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_rest.png")));
}
#Override
public void mousePressed(MouseEvent me) {
if(me.getSource() == prevBtn){
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_pressed.png")));
}else{
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_pressed.png")));
}
}
#Override
public void mouseReleased(MouseEvent me) {
if(me.getSource() == prevBtn)
prevBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_left_hover.png")));
else
nextBtn.setIcon(new ImageIcon(getClass().getClassLoader().getResource("icons/settings_right_hover.png")));
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == nextBtn){
{
if(arrayPointer < clockFace.length){
++arrayPointer;
prevBtn.setEnabled(true);
if(arrayPointer == clockFace.length)
nextBtn.setEnabled(false);
}
clockFaceCount.setText(arrayPointer + " of " + clockFace.length);
setAnalogClockFace(arrayPointer);
}
}else if(ae.getSource() == prevBtn){
{
if(arrayPointer > 1){
--arrayPointer;
nextBtn.setEnabled(true);
if(arrayPointer == 1){
clockFaceCount.setText(arrayPointer+" of "+clockFace.length);
prevBtn.setEnabled(false);
}
}
clockFaceCount.setText(arrayPointer + " of "+clockFace.length);
setAnalogClockFace(arrayPointer);
}
}
}
private void setAnalogClockFace(int pointerPosition) {
try{
image = ImageIO.read(getClass().getClassLoader().getResource(clockFace[pointerPosition]));
}catch(IOException io){
io.printStackTrace();
}
}
public BufferedImage getAnalogClockFace(){
return image;
}
}
I've been working on this for days, can someone please help me understand what am not doing right? Any help would be greatly appreciated.
Here is an MCVE using a JLabel to achieve the same result:
package panels;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.*;
import java.awt.BorderLayout;
#SuppressWarnings({"serial"})
public class ClockPanel extends javax.swing.JPanel implements ActionListener {
private JLabel clockImageLabel;
private JPanel buttonsPanel;
private JButton next,prev;
private JTextField displayCount;
String[] imageFaces;
int pointer = 1;
/**
* Auto-generated main method to display this
* JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new ClockPanel());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public ClockPanel() {
super();
initGUI();
}
private void initGUI() {
try {
setPreferredSize(new Dimension(203, 237));
BorderLayout panelLayout = new BorderLayout();
setLayout(panelLayout);
{
clockImageLabel = new JLabel();
clockImageLabel.setPreferredSize(new Dimension(203,203));
clockImageLabel.setHorizontalAlignment(SwingConstants.CENTER);
clockImageLabel.setVerticalAlignment(SwingConstants.CENTER);
add(clockImageLabel,BorderLayout.NORTH);
}
{
buttonsPanel = new JPanel();
{
next = new JButton(">");
next.addActionListener(this);
}
{
prev = new JButton("<");
prev.addActionListener(this);
displayCount = new JTextField();
displayCount.setBorder(null);
displayCount.setEditable(false);
displayCount.setBackground(getBackground());
displayCount.setHorizontalAlignment(SwingConstants.CENTER);
buttonsPanel.add(prev);
buttonsPanel.add(displayCount);
displayCount.setPreferredSize(new java.awt.Dimension(45, 23));
buttonsPanel.add(next);
add(buttonsPanel,BorderLayout.SOUTH);
}
{
imageFaces = new String[]{"http://imgur.com/T8x0I29",
"http://imgur.com/079QSdJ","http://imgur.com/vQ7tZjI"
};
for(int i = 1; i < imageFaces.length; i++){
if(i == 1){
next.setEnabled(true);
prev.setEnabled(false);
}
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void setLabelImage(int pointerPosition){
clockImageLabel.setIcon(new ImageIcon(getClass().getClassLoader().getResource(imageFaces[pointerPosition])));
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == next){
if(pointer < imageFaces.length){
++pointer;
prev.setEnabled(true);
if(pointer == imageFaces.length)next.setEnabled(false);
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}else if(ae.getSource() == prev){
if(pointer > 1){
--pointer;
next.setEnabled(true);
if(pointer == 1)prev.setEnabled(false);
displayCount.setText(pointer+" of "+imageFaces.length);
setLabelImage(pointer);
}
}
}
}
Here are 1/2 Images for the code:
HandlessAnalogClock 1
HandlessAnalogClock 2
HandlessAnalogClock 3
This MCVE will successfully flip between two of the three images, but still has problems with ArrayIndexOutOfBoundsException.
That last part is 'Batteries Not Included' (left as an exercise for the user to correct).
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
#SuppressWarnings({"serial"})
public class ClockPanel extends JPanel implements ActionListener {
private JLabel clockImageLabel;
private JPanel buttonsPanel;
private JButton next, prev;
private JTextField displayCount;
BufferedImage[] images;
int pointer = 1;
/**
* Auto-generated main method to display this JPanel inside a new JFrame.
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new ClockPanel());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public ClockPanel() {
super();
initGUI();
}
private void initGUI() {
try {
setPreferredSize(new Dimension(203, 237));
BorderLayout panelLayout = new BorderLayout();
setLayout(panelLayout);
clockImageLabel = new JLabel();
clockImageLabel.setPreferredSize(new Dimension(203, 203));
clockImageLabel.setHorizontalAlignment(SwingConstants.CENTER);
clockImageLabel.setVerticalAlignment(SwingConstants.CENTER);
add(clockImageLabel, BorderLayout.NORTH);
buttonsPanel = new JPanel();
next = new JButton(">");
next.addActionListener(this);
prev = new JButton("<");
prev.addActionListener(this);
displayCount = new JTextField();
displayCount.setBorder(null);
displayCount.setEditable(false);
displayCount.setBackground(getBackground());
displayCount.setHorizontalAlignment(SwingConstants.CENTER);
buttonsPanel.add(prev);
buttonsPanel.add(displayCount);
displayCount.setPreferredSize(new java.awt.Dimension(45, 23));
buttonsPanel.add(next);
add(buttonsPanel, BorderLayout.SOUTH);
String[] imageFaces = new String[]{
"http://i.imgur.com/T8x0I29.png",
"http://i.imgur.com/079QSdJ.png",
"http://i.imgur.com/vQ7tZjI.png"
};
images = new BufferedImage[imageFaces.length];
for (int ii=0; ii<imageFaces.length; ii++) {
System.out.println("loading image: " + ii);
images[ii] = ImageIO.read(new URL(imageFaces[ii]));
System.out.println("loaded image: " + images[ii]);
}
setLabelImage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setLabelImage(int pointerPosition) {
System.out.println("setLabelImage: " + pointerPosition);
clockImageLabel.setIcon(new ImageIcon(images[pointerPosition]));
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == next) {
if (pointer < images.length) {
++pointer;
prev.setEnabled(true);
if (pointer == images.length) {
next.setEnabled(false);
}
displayCount.setText(pointer + " of " + images.length);
setLabelImage(pointer);
}
} else if (ae.getSource() == prev) {
if (pointer > 1) {
--pointer;
next.setEnabled(true);
if (pointer == 1) {
prev.setEnabled(false);
}
displayCount.setText(pointer + " of " + images.length);
setLabelImage(pointer);
}
}
}
}
Expanding on #Andrew's example, consider arranging for the index of the current image to wrap-around, as shown in the example cited here.
private int pointer = 0;
...
private void initGUI() {
...
setLabelImage(pointer);
...
}
private void setLabelImage(int pointerPosition) {
System.out.println("setLabelImage: " + pointerPosition);
clockImageLabel.setIcon(new ImageIcon(images[pointerPosition]));
displayCount.setText((pointerPosition + 1) + " of " + images.length);
this.repaint();
}
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == next) {
pointer++;
if (pointer >= images.length) {
pointer = 0;
}
} else if (ae.getSource() == prev) {
pointer--;
if (pointer < 0) {
pointer = images.length - 1;
}
}
setLabelImage(pointer);
}
As an exercise, try to factor out the repeated instantiation of ImageIcon in setLabelImage() by creating a List<ImageIcon> in initGUI().
I've created an Applet that creates a row of buttons, up to 15 buttons, when you push the "add to queue" button. I now want to decrement that row using a for loop. I want it to decrement from left to right. I can only get it to decrement from right to left. I know it has to do with the code in my "Remove" method, but I can't seem to figure out how to fix it. As a newbie I would appreciate any help you can provide.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class Main extends javax.swing.JApplet {
private final int width = 60;
private final int height = 24;
private final int maxItems = 15;
private int x = 40 + width;
private int y = 260;
private int count = 1;
private JButton jAdd;
private JButton jRemove;
Vector<JButton> stack = new Vector<JButton>();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
Main inst = new Main();
frame.getContentPane().add(inst);
((JComponent) frame.getContentPane()).setPreferredSize(inst
.getSize());
frame.pack();
frame.setVisible(true);
}
});
}
public Main() {
super();
initGUI();
}
private void initGUI() {
try {
this.setSize(719, 333);
getContentPane().setLayout(null);
{
jAdd = new JButton();
getContentPane().add(jAdd);
jAdd.setText("Add to Queue");
jAdd.setBounds(43, 300, 150, 24);
jAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jAddActionPerformed(evt);
}
});
}
{
jRemove = new JButton();
getContentPane().add(jRemove);
jRemove.setText("Remove from queue");
jRemove.setBounds(950, 300, 150, 24);
jRemove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jRemoveActionPerformed(evt);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void jAddActionPerformed(ActionEvent evt) {
if (count > maxItems) {
JOptionPane.showMessageDialog(null, "The queue is full");
return;
}
JButton b = new JButton();
stack.add(0, b);
getContentPane().add(b);
int textCount = count;
b.setText("" +textCount++);
b.setBounds(x, y, width, height);
x = x + width;
count++;
}
private void jRemoveActionPerformed(ActionEvent evt) {
if (stack.isEmpty()) {
JOptionPane.showMessageDialog(null, "The queue is empty");
return;
}
JButton b = stack.remove(0);
this.remove(b);
for(int originalX = 880; originalX < 880; originalX--){
x = 880 - width;
}
repaint();
count--;
}
}
The issue is this:
stack.add(0, b);
You are always adding the new one to the start of the Vector (index 0). Remove that and you will see the behavior you want.
stack.add(b);
I have a JPanel where I have components which are moveable.
My problem is that if I use a action in the panel the locations of components in the whole panel are changing theire position to top mid for just a frame than changing back theire positions. I debugged it and know that its coming from validate(). If I use validate() manually it happens without actions, too.
So here is the code for the components that are used in the panel:
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.designtime.DataSourcePlugin;
import com.inform_ac.utils.misc.gui.resizer.ComponentResizer;
/**
* AButton is a JAVA-Swing component with integrated functional buttons.
*/
public class AButton extends JPanel {
/**
* SerialVersionUID: 111111111L
*/
protected static final long serialVersionUID = 111111111L;
/**
* Standard font for displaying text.
*/
protected Font standardFont = new Font("Dialog", Font.PLAIN, 12);
/**
* Defining functional JButtons to delete and edit a AButton.
*/
protected ADeleteButton delBtn = new ADeleteButton(this);
protected JButton editBtn = new JButton();
protected String[] editOptionNames = { "Connect", "Deconnect", "Edit" };
protected JPopupMenu popupmenu = new JPopupMenu();
protected Dimension minDimension = new Dimension(120,120);
protected Point location = new Point();
protected DataFactory dataFactory;
protected DataSourcePlugin dataSourcePlugin;
/**
* Mode: 0 - moving
* 1 - connecting
*/
protected int mode = 0;
/**
* Defining the label for displaying OK or error images.
*/
protected JLabel lblIcon = new JLabel();
protected final JLabel lblInfo1 = new JLabel();
protected final JLabel lblInfo2 = new JLabel();
protected final JLabel lblInfo3 = new JLabel();
public final JButton connectBtn_right = new JButton();
public final JButton connectBtn_left = new JButton();
protected AButton parent;
protected ArrayList<AButton> children = new ArrayList<AButton>();
/**
* Identifier
*/
protected int id = 0;
/**
* Constructor with given start coordinates.
*
* #param X
* - coordinate
* #param Y
* - coordinate
*/
public AButton(int X, int Y, int index) {
this.id = index;
location = new Point(X,Y);
setBounds(location.x, location.y, minDimension.width, minDimension.height);
init();
}
/**
* Private method to initialize main components.
*/
private void init() {
initPnl();
initBtns();
setVisible(true);
setFocusable(true);
}
/**
* Private method to initialize the main panel.
*/
private void initPnl() {
setBackground(UIManager.getColor("InternalFrame.activeTitleBackground"));
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
setPreferredSize(minDimension);
setBorder(UIManager.getBorder("CheckBox.border"));
setFont(standardFont);
setLayout(null);
}
/**
* Private method to initialize functional {#linkplain JButton}.
*/
private void initBtns() {
initEditBtn();
initDelBtn();
initIconPnl();
initConnectorBtns();
}
/**
* Private method to initialize the delete button. Method have to refresh
* the size of this AButton to set the button on the top right corner of
* this AButton.
*/
private void initDelBtn() {
delBtn.setBounds(getWidth() - 18 - 2, 2, 18, 18);
delBtn.setFont(standardFont);
delBtn.setBackground(null);
delBtn.setBorderPainted(false);
delBtn.setBorder(null);
delBtn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
delBtn.setPreferredSize(new Dimension(16, 16));
delBtn.setMinimumSize(new Dimension(12, 12));
delBtn.setMaximumSize(new Dimension(20, 20));
delBtn.setIcon(new ImageIcon(AButton.class
.getResource("/javax/swing/plaf/metal/icons/ocean/close.gif")));
add(delBtn);
}
/**
* Private method to initialize the edit button.
*/
private void initEditBtn() {
initPopupmenu();
initMouseListener();
editBtn.setBounds(2,2,21,21);
editBtn.setFont(standardFont);
editBtn.setBorder(null);
editBtn.setBorderPainted(false);
editBtn.setBackground(UIManager
.getColor("InternalFrame.activeTitleGradient"));
editBtn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
editBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
editBtn.setPreferredSize(new Dimension(21, 21));
editBtn.setMinimumSize(new Dimension(18, 18));
editBtn.setMaximumSize(new Dimension(25, 25));
editBtn.setIcon(new ImageIcon("C:\\Users\\akaradag\\Pictures\\JavaIcon\\icon_bearbeiten.gif"));
add(editBtn);
}
protected void initPopupmenu(){
for(int i = 0; i < editOptionNames.length; i++) {
popupmenu.add(new AbstractAction(editOptionNames[i]) {
private static final long serialVersionUID = 5550466652812249477L;
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Connect")) {
if (mode == 1) {
mode = 0;
showConnectors();
} else {
mode = 1;
showConnectors();
}
} else if (e.getActionCommand().equals("Deconnect")) {
resetConnections();
}
else if(e.getActionCommand().equals("Edit")) {
}
}
});
}
}
protected void initMouseListener()
{
editBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
popupmenu.show(e.getComponent(), e.getX(), e.getY());
}
});
}
/**
* Private method to display or not display the connector buttons
*/
public void showConnectors() {
boolean connect = false;
if (mode == 1) {
connect = true;
}
connectBtn_left.setVisible(connect);
connectBtn_right.setVisible(connect);
}
/**
* Private method to initialize the connector buttons
*/
private void initConnectorBtns() {
connectBtn_right.setCursor(Cursor
.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
connectBtn_right.setVisible(false);
connectBtn_right.setPreferredSize(new Dimension(15, 15));
connectBtn_right.setMinimumSize(new Dimension(12, 12));
connectBtn_right.setMaximumSize(new Dimension(15, 15));
connectBtn_right.setFont(new Font("Dialog", Font.PLAIN, 12));
connectBtn_right.setBorderPainted(false);
connectBtn_right.setBorder(null);
connectBtn_right.setBackground(SystemColor.activeCaption);
connectBtn_right
.setBounds(getWidth() - 16, getHeight() / 2 - 5, 15, 15);
add(connectBtn_right);
connectBtn_left.setCursor(Cursor
.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
connectBtn_left.setVisible(false);
connectBtn_left.setPreferredSize(new Dimension(25, 25));
connectBtn_left.setMinimumSize(new Dimension(12, 12));
connectBtn_left.setMaximumSize(new Dimension(15, 15));
connectBtn_left.setFont(new Font("Dialog", Font.PLAIN, 12));
connectBtn_left.setBorderPainted(false);
connectBtn_left.setBorder(null);
connectBtn_left.setBackground(SystemColor.activeCaption);
connectBtn_left.setBounds(2, getHeight() / 2 - 5, 15, 15);
add(connectBtn_left);
}
/**
* Private method to initialize the {#linkplain JLabel} for displaying
* informations.
*/
private void initIconPnl() {
lblIcon.setHorizontalTextPosition(SwingConstants.CENTER);
lblIcon.setHorizontalAlignment(SwingConstants.CENTER);
lblIcon.setAlignmentX(Component.CENTER_ALIGNMENT);
lblIcon.setIcon(new ImageIcon(AButton.class
.getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
lblIcon.setBorder(null);
lblIcon.setFont(new Font("Dialog", Font.PLAIN, 12));
lblIcon.setBounds(getWidth() / 4, 3, getWidth() / 2,
getHeight() / 4 + 2);
lblIcon.setLayout(null);
add(lblIcon);
lblInfo1.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
lblInfo1.setForeground(SystemColor.desktop);
lblInfo1.setBounds(22, getHeight() / 2 - 5, getWidth() - 42,
getHeight() / 8);
add(lblInfo1);
lblInfo2.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
lblInfo2.setForeground(Color.BLACK);
lblInfo2.setBounds(10, getHeight() / 2 - 5 + getHeight() / 8 + 5,
getWidth() - 20, getHeight() / 8);
add(lblInfo2);
lblInfo3.setFont(new Font("Tahoma", Font.BOLD, getHeight() / 10));
lblInfo3.setForeground(Color.BLACK);
lblInfo3.setBounds(10, getHeight() / 2 - 5 + 2 * (getHeight() / 8 + 5),
getWidth() - 20, getHeight() / 8);
add(lblInfo3);
}
public String getLblInfo(int index) {
if (index == 1) {
return lblInfo1.getText();
} else if (index == 2) {
return lblInfo2.getText();
} else {
return lblInfo3.getText();
}
}
public void setLblInfo(String text, int index) {
if (index == 1) {
lblInfo1.setText(text);
} else if (index == 2) {
lblInfo2.setText(text);
} else {
lblInfo3.setText(text);
}
}
public Point getLocation() {
return new Point(getX(), getY());
}
public Point getInputLocation() {
return connectBtn_left.getLocation();
}
/**
* Methode um die Location des Objektes zu ändern und dies auch zu repainten.
* Dient dazu damit der Fehler das wenn ein Objekt gelöscht wird die restlichen in die Mitte
* wandern.
*/
public void setLocation(Point p){
location = p;
}
public Point getOutputLocation() {
return connectBtn_right.getLocation();
}
public int getMode() {
return mode;
}
public void setMode(int mode) {
this.mode = mode;
showConnectors();
}
public JButton getDelBtn() {
return delBtn;
}
public int getIndex() {
return id;
}
public void setIndex(int index) {
this.id = index;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setLocation(location.x, location.y);
if (lblInfo1.getText().equals("Join")) {
if (children.size() == 2) {
lblIcon.setIcon(new ImageIcon(
"C:\\Users\\akaradag\\Pictures\\JavaIcon\\ok-icon.png"));
} else if (children.size() > 2) {
lblIcon.setIcon(new ImageIcon(
AButton.class
.getResource("/javax/swing/plaf/metal/icons/ocean/warning.png")));
} else {
lblIcon.setIcon(new ImageIcon(
AButton.class
.getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
}
} else if (lblInfo1.getText().equals("JDBC")
|| lblInfo1.getText().equals("File")) {
if (parent != null) {
lblIcon.setIcon(new ImageIcon(
"C:\\Users\\akaradag\\Pictures\\JavaIcon\\ok-icon.png"));
} else {
lblIcon.setIcon(new ImageIcon(
AButton.class
.getResource("/javax/swing/plaf/metal/icons/ocean/error.png")));
}
}
}
public void setOutput(AButton out) {
parent = out;
}
public AButton getOutput() {
return parent;
}
public void addInput(AButton input) {
if (!contains(input)) {
this.children.add(input);
}
}
private boolean contains(AButton in) {
for (int i = 0; i < this.children.size(); i++) {
if (this.children.get(i).getIndex() == in.getIndex()) {
return true;
}
}
return false;
}
public ArrayList<AButton> getInput() {
return this.children;
}
public void removeFromInput(AButton remove) {
for (int i = 0; i < this.children.size(); i++) {
if (this.children.get(i) != null) {
if (this.children.get(i).getIndex() == remove.getIndex()) {
this.children.remove(i);
}
}
}
}
public void resetConnections() {
if (parent != null) {
ArrayList<AButton> in = parent.getInput();
for (int i = 0; i < in.size(); i++) {
if (in.get(i).getIndex() == id) {
in.remove(i);
}
}
parent = null;
}
for (int i = 0; i < this.children.size(); i++) {
this.children.get(i).setOutput(null);
this.children.get(i).repaint();
}
this.children = new ArrayList<AButton>();
// if(connectionsDeletedNotify != null)
// connectionsDeletedNotify.actionPerformed(new ActionEvent(this, 0, "Deconnect"));
}
/**
* Setter for the DataFactory
* #param df
*/
public void setDataFactory(DataFactory df)
{
this.dataFactory = df;
}
/**
* Getter for the DataFactory
* #return
*/
public DataFactory getDataFactory()
{
return this.dataFactory;
}
public DataSourcePlugin getDataSourcePlugin() {
return dataSourcePlugin;
}
public void setDataSourcePlugin(DataSourcePlugin dataSourcePlugin) {
this.dataSourcePlugin = dataSourcePlugin;
}
}
Here is the code of the main panel
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.designtime.DataSourcePlugin;
import org.pentaho.reporting.engine.classic.core.designtime.DefaultDataFactoryChangeRecorder;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.DataintegratorDesignTimeContext;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.AButton;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.AConfirmDialog;
import com.inform_ac.reporting.datasource.dataintegrator.frontend.component.ADeleteButton;
public class DataintegratorMainPanel extends JPanel {
DataintegratorDesignTimeContext context;
JPopupMenu popmen = new JPopupMenu();
JMenuItem menu1 = new JMenuItem("Add new Datasource:");
JMenuItem menu2 = new JMenuItem("Join");
Dimension dim = new Dimension();
Point holdingPoint , point1, point2;;
/**
* ArrayList für die visuellen Datasources
*/
ArrayList<AButton> abuttonList = new ArrayList<AButton>();
/**
* Nummerierungen der abuttons
*/
int index = 0;
/**
* The <code>Logger</code> of this instance
*/
protected final static Logger LOGGER = LoggerFactory.getLogger(DataintegratorQueryPanel.class);
private static final long serialVersionUID = 4705352682546516889L;
public DataintegratorMainPanel() {
initPopupMenu();
initMouseListener();
}
protected void initMouseListener()
{
this.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3){
popmen.show(e.getComponent(), e.getX(), e.getY());
}
}
});
}
/**
* Überschrift bei Rechtsklick
* #param header
* #return JComponent
*/
protected JComponent createHeader(String header) {
JLabel label = new JLabel(header);
label.setFont(label.getFont().deriveFont(Font.BOLD,14));
label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
return label;
}
protected void giveMouseListenerTo(AButton button) {
button.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseDragged(MouseEvent me) {
super.mouseDragged(me);
AButton tmp = (AButton) me.getSource();
//Mode Moving
if(tmp.getMode()==0){
Point point = getMousePosition();
//Über den Rand raus
if(point != null) {
point.x = point.x - holdingPoint.x;
point.y = point.y - holdingPoint.y;
if(point.x >= 0 && point.y >= 0) {
tmp.setLocation(point);
}
//LOGGER.info(""+point);
}
}
else if (tmp.getMode()==1) {
point2 = getMousePosition();
}
repaint();
}
});
button.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent me) {
super.mousePressed(me);
AButton tmp = (AButton) me.getSource();
if (tmp.getMode() == 0) {
holdingPoint = tmp.getMousePosition();
}
else if (tmp.getMode() == 1) {
Point tmp_point = tmp.getLocation();
point1 = new Point(tmp.connectBtn_right.getLocation().x+tmp_point.x,tmp.connectBtn_right.getLocation().y+tmp_point.y);
LOGGER.info("point1: "+point1);
}
}
#Override
public void mouseReleased(MouseEvent me) {
super.mouseReleased(me);
try {
AButton destination = (AButton) getComponentAt(getMousePosition());
AButton source = (AButton) me.getSource();
if (destination != null && source.getMode() == 1) {
// Hier muss der Baum verkettet werden
if (destination != source) {
destination.addInput(source);
if (source.getOutput() == null) {
source.setOutput(destination);
} else {
AButton tmp = source.getOutput();
tmp.removeFromInput(source);
source.setOutput(destination);
}
source.setMode(0);
destination.setMode(0);
}
}
} catch (ClassCastException e) {
point2 = null;
}
point1 = null;
point2 = null;
repaint();
}
});
repaint();
}
protected void initPopupMenu() {
popmen.add(createHeader("Neue Datasource"));
popmen.addSeparator();
context = new DataintegratorDesignTimeContext(new MasterReport());
final DataFactoryMetaData[] datas = DataFactoryRegistry.getInstance()
.getAll();
for (final DataFactoryMetaData data : datas) {
// Some of the DataFactories are not needed
if (data.isHidden()) {
continue;
} else if (!WorkspaceSettings.getInstance().isShowExpertItems()
&& data.isExpert()) {
continue;
} else if (!WorkspaceSettings.getInstance().isShowDeprecatedItems()
&& data.isDeprecated()) {
continue;
} else if (!WorkspaceSettings.getInstance()
.isExperimentalFeaturesVisible() && data.isExperimental()) {
continue;
} else if (!data.isEditorAvailable()) {
continue;
}
if (data.getDisplayName(getLocale()).equals("Dataintegrator")) {
continue;
}
JMenuItem item = new JMenuItem(new AbstractAction(
data.getDisplayName(getLocale())) {
private static final long serialVersionUID = 7700562297221703939L;
#Override
public void actionPerformed(ActionEvent arg0) {
Point mousePos = getMousePosition();
final AButton tmp = new AButton(mousePos.x,mousePos.y,index++);
// Action listener hier und nicht in die for schleife
tmp.getDelBtn().addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ADeleteButton tmp_1 = (ADeleteButton) arg0
.getSource();
AButton source = tmp_1.getAbutton();
AConfirmDialog dialog = new AConfirmDialog();
int opt = dialog.getState();
if (opt == 1) {
for (int i = 0; i < abuttonList.size(); i++) {
if (source.getIndex() != abuttonList.get(i)
.getIndex()) {
if (abuttonList.get(i).getOutput() != null
&& abuttonList.get(i).getOutput()
.getIndex() == source
.getIndex()) {
abuttonList.get(i).setOutput(null);
}
abuttonList.get(i).removeFromInput(source);
}
}
// seperat erst die referenzen löschen dann das
// objekt aus der liste
for (int i = 0; i < abuttonList.size(); i++) {
if (source.getIndex() == abuttonList.get(i)
.getIndex()) {
abuttonList.remove(i);
source.setVisible(false);
source.setEnabled(false);
}
}
}
}
});
LOGGER.info("--> data: " + data);
final DataSourcePlugin editor = data.createEditor();
LOGGER.info("--> editor: " + editor);
final DefaultDataFactoryChangeRecorder recorder = new DefaultDataFactoryChangeRecorder();
final DataFactory dataFactory = editor.performEdit(context,
null, null, recorder);
LOGGER.info("--> datafactory: " + dataFactory);
// Falls die Datafactory initialisiert werden konnte
if (dataFactory != null) {
tmp.setDataSourcePlugin(editor);
tmp.setDataFactory(dataFactory);
add(tmp);
//LOGGER.info("New datafact"+mousePos);
abuttonList.add(tmp);
//Moving listener
giveMouseListenerTo(tmp);
validate();
}
}
});
popmen.add(item);
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(1.5f));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Line2D tmp_line;
for (int i = 0; i < abuttonList.size(); i++) {
if (abuttonList.get(i).getOutput() != null) {
g2d.setStroke(new BasicStroke(1.5f));
int x1 = abuttonList.get(i).getLocation().x
+ abuttonList.get(i).connectBtn_right.getLocation().x;
int y1 = abuttonList.get(i).getLocation().y
+ abuttonList.get(i).connectBtn_right.getLocation().y;
int x2 = abuttonList.get(i).getOutput().getLocation().x
+ abuttonList.get(i).getOutput().connectBtn_left
.getLocation().x - 4;
int y2 = abuttonList.get(i).getOutput().getLocation().y
+ abuttonList.get(i).getOutput().connectBtn_left
.getLocation().y;
tmp_line = new Line2D.Double(x1, y1, x2, y2);
double m = (y2 - y1) / (double) (x2 - x1);
//logger.info("m: "+m);
int vz = x2-x1;
//LOGGER.info("vz: "+vz);
if(vz<0)
{
vz = 20;
}
else if (vz>0){
vz = -20;
}
if(m<4 && m>-4) {
Point p = new Point(x2 -20, (int) (y1 + m * (x2 - x1 - 20)));
//logger.info(p.toString());
Line2D tmp2_line = new Line2D.Double(x2, y2, x2 + vz,
p.y + 3);
//logger.info("x2: "+x2+", y2: "+y2+", p.y:"+p.y);
Line2D tmp3_line = new Line2D.Double(x2, y2, x2 + vz,
p.y - 3);
//logger.info("x2: "+x2+", y2: "+y2+", p.y:"+p.y);
g2d.setPaint(Color.BLACK);
g2d.draw(tmp2_line);
g2d.draw(tmp3_line);
}
g2d.draw(tmp_line);
}
}
if (point1 != null && point2 != null) {
Line2D line2d = new Line2D.Double(point1, point2);
g2d.setPaint(Color.RED);
g2d.setStroke(new BasicStroke(1.5f));// set stroke size
g2d.draw(line2d);
}
}
}
So the error happens if I click on the editBtn und click for example on Connect. It repaints the whole panel and the abuttons in the panel are located in the middle top of the panel vertically for some frames and it goes back to the locations that are saved in the object itselft.
Also I can reproduce the error by using validate().
I dont understand what is the problem here. Why its changing the locations of the components in the main panel after a validation?
And sorry if the code is not SSCCE but I couldn't get it work without the pentaho libraries...
Ok I fixed it.
The problem was the default layoutmanager of the JPanel.
After I changed it to setLayout(null); the problem disapears.
I suggest the use of a layout manager, in any respect it is preferable; it may take you some time at first, but is worthy. For simple use cases, built-in ones, like BorderLayout, GridBagLayout may suffice. But, for more control, try MigLayout: complete, elegant, and precise. (http://www.miglayout.com/)
If you ask why, the JavaDoc has it:
void java.awt.Container.validate()
Validates this container and all of its subcomponents.
Validating a container means laying out its subcomponents. Layout-related changes, such as setting the bounds of a component, or adding a component to the container, invalidate the container automatically. Note that the ancestors of the container may be invalidated also (see Component.invalidate for details.) Therefore, to restore the validity of the hierarchy, the validate() method should be invoked on the top-most invalid container of the hierarchy.
Validating the container may be a quite time-consuming operation. For performance reasons a developer may postpone the validation of the hierarchy till a set of layout-related operations completes, e.g. after adding all the children to the container.
If this Container is not valid, this method invokes the validateTree method and marks this Container as valid. Otherwise, no action is performed.
Overrides: validate() in Component