Please am developing a chess game using Java. I am having problems trying to display captured chess pieces, this pieces are held in a bufferedImage. when i run and print the variable of the bufferedImage it isn't null and doesn't display the image on the JPanel.
In addition my list of captured chess piece stored in a "List capturedPiece" and is working fine, also the paths to the images are correct. The only problem is that the image stored on the bufferedImage doesn't displaying.
Here is my code
package chessgame.gui;
public class BrownPlayerPanel extends JPanel {
private Rectangle yellowPawnRect, yellowKnightRect, yellowBishopRect,
yellowRookRect, yellowQueenRect;
private Rectangle brownPawnRect, brownKnightRect, brownBishopRect,
brownRookRect, brownQueenRect;
private List<Piece> capturedPieces;
BufferedImage figurineLayer, counterLayer;
boolean firstPaint = true;
private ImageFactory fact;
BufferedImage piecetest;
public BrownPlayerPanel() {
initComponents();
fact = new ImageFactory();
}
public void setCapturedPieces(List<Piece> piece) {
capturedPieces = piece;
//System.out.println(capturedPieces);
if (counterLayer != null) {
clearBufferedImage(counterLayer);
}
if (figurineLayer != null) {
clearBufferedImage(figurineLayer);
}
updateLayers();
repaint();
}
private void initRects(int width, int height) {
int gridWidth = width / 5;
int gridHeight = height / 2;
yellowPawnRect = new Rectangle(0, 0, gridWidth, gridHeight);
yellowKnightRect = new Rectangle(gridWidth, 0, gridWidth, gridHeight);
yellowBishopRect = new Rectangle(gridWidth * 2, 0, gridWidth, gridHeight);
yellowRookRect = new Rectangle(gridWidth * 3, 0, gridWidth, gridHeight);
yellowQueenRect = new Rectangle(gridWidth * 4, 0, gridWidth, gridHeight);
brownPawnRect = new Rectangle(0, gridHeight, gridWidth, gridHeight);
brownKnightRect = new Rectangle(gridWidth, gridHeight, gridWidth,gridHeight);
brownBishopRect = new Rectangle(gridWidth * 2, gridHeight, gridWidth,gridHeight);
brownRookRect = new Rectangle(gridWidth * 3, gridHeight, gridWidth,gridHeight);
brownQueenRect = new Rectangle(gridWidth * 4, gridHeight, gridWidth,gridHeight);
}
public void clearBufferedImage(BufferedImage image) {
Graphics2D g2d = image.createGraphics();
g2d.setComposite(AlphaComposite.Src);
g2d.setColor(new Color(0, 0, 0, 0));
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
g2d.dispose();
}
private void updateLayers() {
int yPC = 0, yNC = 0, yBC = 0, yRC = 0, yQC = 0;
int bPC = 0, bNC = 0, bBC = 0, bRC = 0, bQC = 0;
if (firstPaint) {
int width = this.getWidth();
int height = this.getHeight();
figurineLayer = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
counterLayer = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
capturedPieces = new ArrayList<Piece>();
initRects(width, height);
firstPaint = false;
}
int width = this.getWidth();
int height = this.getHeight();
int gridWidth = width / 5;
for (Piece piece : capturedPieces) {
if (piece.getColor() == Piece.YELLOW_COLOR) {
if (piece.getType() == Piece.TYPE_PAWN) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.YELLOW_COLOR, Piece.TYPE_PAWN),yellowPawnRect);
yPC++;
}
if (piece.getType() == Piece.TYPE_KNIGHT) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.YELLOW_COLOR,Piece.TYPE_KNIGHT),yellowKnightRect);
yNC++;
}
if (piece.getType() == Piece.TYPE_BISHOP) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.YELLOW_COLOR,Piece.TYPE_BISHOP),yellowBishopRect);
yBC++;
}
if (piece.getType() == Piece.TYPE_ROOK) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.YELLOW_COLOR, Piece.TYPE_ROOK), yellowRookRect);
yRC++;
}
if (piece.getType() == Piece.TYPE_QUEEN) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.YELLOW_COLOR,Piece.TYPE_QUEEN), yellowQueenRect);
yQC++;
}
}
if (piece.getColor() == Piece.BROWN_COLOR) {
if (piece.getType() == Piece.TYPE_PAWN) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.BROWN_COLOR, Piece.TYPE_PAWN),brownPawnRect);
System.out.println(getFigurineImage(Piece.BROWN_COLOR, Piece.TYPE_PAWN).getWidth());
bPC++;
}
if (piece.getType() == Piece.TYPE_KNIGHT) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.BROWN_COLOR,Piece.TYPE_KNIGHT),brownKnightRect);
bNC++;
}
if (piece.getType() == Piece.TYPE_BISHOP) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.BROWN_COLOR,Piece.TYPE_BISHOP),brownBishopRect);
bBC++;
}
if (piece.getType() == Piece.TYPE_ROOK) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.BROWN_COLOR, Piece.TYPE_ROOK),brownRookRect);
bRC++;
}
if (piece.getType() == Piece.TYPE_QUEEN) {
drawImageIntoLayer(figurineLayer, getFigurineImage(Piece.BROWN_COLOR,Piece.TYPE_QUEEN), brownQueenRect);
bQC++;
}
}
}
if (yPC > 1) {
drawCounterIntoLayer(counterLayer, yPC, yellowPawnRect);
}
if (yNC > 1) {
drawCounterIntoLayer(counterLayer, yNC, yellowKnightRect);
}
if (yBC > 1) {
drawCounterIntoLayer(counterLayer, yBC, yellowBishopRect);
}
if (yRC > 1) {
drawCounterIntoLayer(counterLayer, yRC, yellowRookRect);
}
if (yQC > 1) {
drawCounterIntoLayer(counterLayer, yQC, yellowQueenRect);
}
if (bPC > 1) {
drawCounterIntoLayer(counterLayer, bPC, brownPawnRect);
}
if (bNC > 1) {
drawCounterIntoLayer(counterLayer, bNC, brownKnightRect);
}
if (bBC > 1) {
drawCounterIntoLayer(counterLayer, bBC, brownBishopRect);
}
if (bRC > 1) {
drawCounterIntoLayer(counterLayer, bRC, brownRookRect);
}
if (bQC > 1) {
drawCounterIntoLayer(counterLayer, bQC, brownQueenRect);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(figurineLayer, 10,10, this);
g2d.drawImage(counterLayer, null, this);
}
private void drawCounterIntoLayer(BufferedImage canvas, int count,Rectangle whereToDraw) {
Graphics2D g2d = canvas.createGraphics();
g2d.setFont(new Font("Arial", Font.BOLD, 12));
g2d.setColor(Color.black);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
FontMetrics textMetrics = g2d.getFontMetrics();
String countString = Integer.toString(count);
int xCoord = whereToDraw.x + whereToDraw.width - textMetrics.stringWidth(countString);
int yCoord = whereToDraw.y + whereToDraw.height;
g2d.drawString(countString, xCoord, yCoord);
g2d.dispose();
}
private void drawImageIntoLayer(BufferedImage canvas, BufferedImage item,Rectangle r) {
Graphics2D g2d = canvas.createGraphics();
g2d.drawImage(item, r.x, r.y, r.width, r.height, this);
g2d.dispose();
}
private void initComponents() {
setName("Form");
setBounds(0, 0, 250, 146);
setBorder(new LineBorder(new Color(139, 69, 19)));
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 698, Short.MAX_VALUE)
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGap(0, 448, Short.MAX_VALUE)
);
setLayout(groupLayout);
setBackground(Color.black);
}
private BufferedImage getFigurineImage(int color, int type) {
BufferedImage ImageToDraw = null;
try {
String filename = "";
filename += (color == Piece.YELLOW_COLOR ? "Yellow" : "Brown");
switch (type) {
case Piece.TYPE_BISHOP:
filename += "b";
break;
case Piece.TYPE_KING:
filename += "k";
break;
case Piece.TYPE_KNIGHT:
filename += "n";
break;
case Piece.TYPE_PAWN:
filename += "p";
break;
case Piece.TYPE_QUEEN:
filename += "q";
break;
case Piece.TYPE_ROOK:
filename += "r";
break;
}
filename += ".png";
URL urlPiece = getClass().getResource("/chessgame/res/" + filename);
ImageToDraw = ImageIO.read(urlPiece);
} catch (IOException io) {
}
return ImageToDraw;
}
}
ChessWindow Class:
public class ChessWindow extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private BoardGUI boardgui;
private Game game;
JPanel panel_1;
public JLabel lblNewLabel;
private XmlRpcServer server;
private static final int PLAYER_OPTION_SWING = 1;
private static final int PLAYER_OPTION_AI = 2;
private static final int PLAYER_OPTION_NETWORK = 3;
String gameIdOnServer, gamePassword;
public ChessWindow(int yellowPlayerOption, int brownPlayerOption,Game game, String gameIdOnServer, String gamePassword) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 776, 583);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
menuBar.add(mnFile);
JMenuItem mntmNewGame = new JMenuItem("New Game");
mnFile.add(mntmNewGame);
JSeparator separator = new JSeparator();
mnFile.add(separator);
JSeparator separator_1 = new JSeparator();
mnFile.add(separator_1);
JSeparator separator_2 = new JSeparator();
mnFile.add(separator_2);
JMenuItem mntmAccount = new JMenuItem("Account");
mnFile.add(mntmAccount);
JSeparator separator_10 = new JSeparator();
mnFile.add(separator_10);
JMenuItem mntmExit = new JMenuItem("Exit");
mnFile.add(mntmExit);
JMenu mnTactics = new JMenu("Tactics");
menuBar.add(mnTactics);
JMenuItem mntmTactics = new JMenuItem("Tactics 1");
mnTactics.add(mntmTactics);
JMenuItem mntmTactics_1 = new JMenuItem("Tactics 2");
mnTactics.add(mntmTactics_1);
JMenu mnServer = new JMenu("Server");
menuBar.add(mnServer);
JMenuItem mntmServerStatus = new JMenuItem("Server Status");
mntmServerStatus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//String gameId = "Game ID:" + server.getGameIdOnServer();
JOptionPane.showMessageDialog(boardgui,
server.gameIdOnServer,
"A plain message",
JOptionPane.PLAIN_MESSAGE);
}
});
mnServer.add(mntmServerStatus);
JMenuItem mntmServerLog = new JMenuItem("Server Log");
mntmServerLog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JavaConsole console = new JavaConsole();
console.frame.setVisible(true);
console.frame.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
}
});
mnServer.add(mntmServerLog);
JMenuItem mntmViewOnlinePlayers = new JMenuItem("View Online Players");
mnServer.add(mntmViewOnlinePlayers);
JMenu mnStatistics = new JMenu("Statistics");
menuBar.add(mnStatistics);
JMenuItem mntmHumanStatsAgainst = new JMenuItem("Human Stats Against Computer");
mnStatistics.add(mntmHumanStatsAgainst);
JSeparator separator_8 = new JSeparator();
mnStatistics.add(separator_8);
JMenuItem mntmComputerStatsAgainst = new JMenuItem("Computer Stats Against Itself");
mnStatistics.add(mntmComputerStatsAgainst);
JSeparator separator_9 = new JSeparator();
mnStatistics.add(separator_9);
JMenuItem mntmHumanStatsAgains = new JMenuItem("Human Stats Agains Human");
mnStatistics.add(mntmHumanStatsAgains);
JMenuItem mntmAlgorithmInformation = new JMenuItem("Algorithm Information");
mnStatistics.add(mntmAlgorithmInformation);
JMenu mnOptions = new JMenu("Options");
menuBar.add(mnOptions);
JMenu mnTest = new JMenu("Test");
mnOptions.add(mnTest);
JMenuItem mntmPiecePosition = new JMenuItem("Piece Position");
mnTest.add(mntmPiecePosition);
JMenuItem mntmPieceMoves = new JMenuItem("Piece Moves");
mnTest.add(mntmPieceMoves);
JSeparator separator_11 = new JSeparator();
mnOptions.add(separator_11);
JMenuItem mntmConsole = new JMenuItem("Console");
mntmConsole.addActionListener(new ConsoleController());
mnOptions.add(mntmConsole);
JMenu mnHelp = new JMenu("Help");
menuBar.add(mnHelp);
JMenuItem mntmRulesOfChess = new JMenuItem("Rules of Chess");
mnHelp.add(mntmRulesOfChess);
JMenuItem mntmAbout = new JMenuItem("About");
mnHelp.add(mntmAbout);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.NORTH);
panel.setBounds(0, 0, 50, 50);
lblNewLabel = new JLabel("text");
panel.add(lblNewLabel);
JSplitPane splitPane = new JSplitPane();
splitPane.setResizeWeight(0.1);
contentPane.add(splitPane, BorderLayout.CENTER);
game = new Game();
boardgui = new BoardGUI(game);
splitPane.setLeftComponent(boardgui);
GameConfig(yellowPlayerOption, brownPlayerOption, game, gameIdOnServer, gamePassword, boardgui);
StatusPanel panel_1 = new StatusPanel();
contentPane.add(panel_1, BorderLayout.SOUTH);
boardgui.lblGameState = new JLabel();
panel_1.add(boardgui.lblGameState);
JPanel panel_2 = new JPanel();
splitPane.setRightComponent(panel_2);
panel_2.setBounds(0, 0, 50, 300);
panel_2.setLayout(null);
BrownPlayerPanel brown = new BrownPlayerPanel();
panel_2.add(brown);
MovesHistoryPanel moveDisplay = new MovesHistoryPanel();
moveDisplay.setBorder(new LineBorder(new Color(139, 69, 19)));
panel_2.add(moveDisplay);
YellowPlayerPanel yellow = new YellowPlayerPanel();
yellow.setBorder(new LineBorder(new Color(139, 69, 19)));
panel_2.add(yellow);
}
}
Given these things you stated are true:
when i run and print the variable of the bufferedImage it isn't null
In addition my list of captured chess piece stored in a "List capturedPiece" and is working fine
also the paths to the images are correct.
A common problem will custom painting that the panel that the painting is being done on has not default preferred size (0x0). A panel only get increased preferred size based on more components being added to it. In the case of custom painting on a panel, you need to give the panel an explicit preferred size by overriding getPreferredSize()
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
Without this, it can be hit or miss, whether or not you will see the contents of the panel. The determining factory is the layout manager of the parent container. Some layout managers will respect the preferred size (in which case, you won't see the contents) and some that won't respect preferred size (in which case, the panel will stretch to fit the container - where you may see the contents). Generally when custom painting, you always want to override the method. Have a look at this post to get an idea of which layout managers respect preferred sizes and which ones don't
If that doesn't work, I suggest you post an MCVE that we can run and test. Leave out all the unnecessary code that doesn't pertain to this problem. I'd sat just create a separate program that has nothing to do with your program, just a couple simple images being drawn to a panel, and add it to a frame. Something simple recreates the problem.
UPDATE
Don't use null layouts! Use layout managers.. Your layout a null for the container you want to add the panel in question to, but you can't do that without setting the bounds. But forget that. Like I said, don't use null layouts. Learn to use the layout managers in the link. Let them do the position and sizing for you.
Related
I'm making a game and when the user is in one of the game map panels he should enter the game once the character rectangle intersects with the game button rectangle on the map. The user navigates the character using the arrow keys.
I have the following code in the keyPressed method for one of the map panels (its the same for the rest) and the button (game1) reacts to the intersection as it should but the add and remove statements aren't adding or removing the respective panels:
Rectangle rb1 = character.getBounds();
Rectangle rb2 = game1.getBounds();
if (rb1.intersects(rb2)){
game1.setText("Int");
game1.setBackground(Color.red);
remove(sp);
add(g1, "Center");
validate();
repaint();
}
Initially I thought putting that block in the keyPressed method was what's causing the issue but when i moved it, the game1 button stopped reacting entirely. Any help is welcomed and appreciated :)
Here is the code in that panel:
public class SportsPanel extends javax.swing.JPanel implements KeyListener {
JButton homeButton2;
JButton game1;
JButton game2;
JButton game3;
JButton game4;
JButton game5;
SportsPanel sp;
JLabel character;
CharacterMenu cm;
ControlPanel cp;
game1 g1;
game2 g2;
game3 g3;
game4 g4;
game5 g5;
JTextField scoreField;
int c =1;
int x = 100;
int y = 100;
public SportsPanel() {
cm = new CharacterMenu();
g1 = new game1();
g2 = new game2();
g3 = new game3();
g4 = new game4();
g5 = new game5();
setLayout(null);
setBackground(Color.white);
homeButton2 = new JButton("Back to Main Menu");
add(homeButton2);
homeButton2.setBounds(10, 629, 150, 40);
character = new JLabel("");
character.setBounds(x, y, 100, 100);
add(character);
game1 = new JButton("Game 1");
add(game1);
game1.setBounds(200,200, 100, 20);
game2 = new JButton("Game 2");
add(game2);
game2.setBounds(340, 20, 100, 20);
game3 = new JButton("Game 3");
add(game3);
game3.setBounds(120,458, 100, 20);
game4 = new JButton("Game 4");
add(game4);
game4.setBounds(458,269, 100, 20);
game5 = new JButton("Game 5");
add(game5);
game5.setBounds(2, 500, 100, 20);
setFocusable(true);
addKeyListener(this);
scoreField = new JTextField(" Time elapsed: ");
scoreField.setBounds(10, 10, 150, 50);
add(scoreField);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
requestFocusInWindow();
Image myImage = Toolkit.getDefaultToolkit().getImage("images/sports.png");
g.drawImage(myImage, 0, 0, 925, 699, this);
if(c == 1){
ImageIcon lion1 = new ImageIcon("images/lion.png");
ImageIcon newSize = new ImageIcon(((lion1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
if(c == 2){
ImageIcon franklin1 = new ImageIcon("images/franklin.png");
ImageIcon newSize = new ImageIcon(((franklin1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
if(c == 3){
ImageIcon saquon1 = new ImageIcon("images/saquon.png");
ImageIcon newSize = new ImageIcon(((saquon1).getImage()).getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH));
character.setText("");
character.setIcon(newSize);
}
}
#Override
public void keyTyped(KeyEvent evt) {
}
#Override
public void keyPressed(KeyEvent evt) {
System.out.println("Key pressed");
int kk = evt.getKeyCode();
if (kk == evt.VK_LEFT)
{
x = x - 5;;
}
if (kk == evt.VK_RIGHT)
{
x = x + 5;
}
if (kk == evt.VK_UP)
{
y = y - 5;
}
if (kk == evt.VK_DOWN)
{
y = y + 5;
}
character.setBounds(new Rectangle(x, y, 100, 100));
Rectangle rb1 = character.getBounds();
Rectangle rb2 = game1.getBounds();
if (rb1.intersects(rb2)){
game1.setText("Int");
game1.setBackground(Color.red);
remove(sp);
add(g1, "Center");
validate();
repaint();
}
}
#Override
public void keyReleased(KeyEvent evt) {
}
}
I'm trying to make a pong game by using Swing. I have a menu screen where you can change your preferences such as music, game speed and you can choose multiplayer options etc. But when I made a choice, their values don't change. I have my mainmenu class and computer class.
For ex: I want to change the difficulty which means changing the AI's speed but I wasn't be able to do it. I am looking forward for an answer, maybe it's so simple but I can't see it.
This is my code:
public class MenuPanel
{
ScoreBoard sc = new ScoreBoard();
private JFrame mainFrame;
private JFrame optionsFrame;
private JPanel menuPanel;
private JPanel optionsPanel;
private JFrame gameEndFrame;
private JPanel gameEndPanel;
JCheckBox twoPlayer;
// creating the swing components and containers,
// there are two frames to swap between them,
// we tried to use cardLayout but it didn't work for us.
public MenuPanel() {
mainFrame = new JFrame("Welcome To Pong Game");
mainFrame.setSize(700,700);
mainFrame.setLayout(new CardLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuPanel = new JPanel(null);
menuPanel.setSize(700,700);
menuPanel.setVisible(true);
mainFrame.add(menuPanel);
optionsFrame = new JFrame("Settings");
optionsFrame.setSize(700, 700);
optionsFrame.setLayout(new CardLayout());
optionsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel optionsPanel = new JPanel(null) ;
optionsPanel.setSize(700,700);
optionsPanel.setVisible(true);
optionsFrame.add(optionsPanel);
// mainPanel components
ImageIcon ic1 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Actions-player-play-icon.png");
ImageIcon ic2 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Settings-L-icon.png");
ImageIcon ic3 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\cup-icon.png");
ImageIcon ic4 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Button-Close-icon.png");
ImageIcon ic5 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\ice-2025937_960_720.jpg");
ImageIcon ic6 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\tenis1.png");
JLabel mainLabel = new JLabel();
Font font = new Font("Papyrus", Font.BOLD,26);
mainLabel.setFont(font);
mainLabel.setForeground(Color.RED);
mainLabel.setText("PONG GAME");
JButton startButton = new JButton("Start Game");
JButton optionsButton = new JButton("Options");
JButton leaderButton = new JButton("Leaderboard");
JButton exitButton = new JButton("Exit");
JButton icb1 = new JButton(ic1);
JButton icb2 = new JButton(ic2);
JButton icb3 = new JButton(ic3);
JButton icb4 = new JButton(ic4);
JButton icb6 = new JButton(ic6);
// at first, we tried to keep our buttons and labels in panels
// but then we didn't add an image to label as the background
// so we created a JLabel to set its image as the background, we may remove it later.
JLabel mn = new JLabel(ic5);
mn.setBackground(Color.BLUE);
mn.setBounds(1, 1, 700, 700);
Font font3 = new Font("Calibri", Font.PLAIN, 20);
twoPlayer = new JCheckBox();
twoPlayer.setFont(font3);
twoPlayer.setForeground(Color.DARK_GRAY);
twoPlayer.setText(" MultiPlayer");
twoPlayer.setBounds(200, 350, 220, 40);
menuPanel.add(mn);
mn.add(mainLabel);
mn.add(startButton);
mn.add(optionsButton);
mn.add(leaderButton);
mn.add(exitButton);
mn.add(icb1);
mn.add(icb2);
mn.add(icb3);
mn.add(icb4);
mn.add(icb6);
mn.add(twoPlayer);
mainFrame.setVisible(true);
// the components added by their coordinates to make them look formal
mainLabel.setBounds(210, 100, 220, 40);
startButton.setBounds(200, 150, 220, 40);
optionsButton.setBounds(200, 200, 220, 40);
leaderButton.setBounds(200, 250, 220, 40);
exitButton.setBounds(200, 300, 220, 40);
icb1.setBounds(150, 150, 40, 40);
icb2.setBounds(150, 200, 40, 40);
icb3.setBounds(150, 250, 40, 40);
icb4.setBounds(150, 300, 40, 40);
icb6.setBounds(150,350,40,40);
startButton.setBorder(BorderFactory.createRaisedBevelBorder());
optionsButton.setBorder(BorderFactory.createRaisedBevelBorder());
leaderButton.setBorder(BorderFactory.createRaisedBevelBorder());
exitButton.setBorder(BorderFactory.createRaisedBevelBorder());
// optionsPanel components
JButton doneButton = new JButton("Done");
doneButton.setBounds(150,330,220,40);
doneButton.setBorder(BorderFactory.createRaisedBevelBorder());
Font font1 = new Font("Calibri", Font.PLAIN,24);
Font font2 = new Font("Calibri", Font.BOLD,19);
JLabel st = new JLabel();
st.setFont(font1);
st.setForeground(Color.DARK_GRAY);
st.setText("-OPTIONS-");
JLabel difficulty = new JLabel("Difficulty: ");
difficulty.setFont(font2);
difficulty.setForeground(Color.DARK_GRAY);
JLabel music = new JLabel("Sound: ");
music.setFont(font2);
music.setForeground(Color.DARK_GRAY);
JLabel gSpeed = new JLabel("Game Speed: ");
gSpeed.setFont(font2);
gSpeed.setForeground(Color.DARK_GRAY);
JLabel screen = new JLabel(ic5);
screen.setBackground(Color.BLUE);
screen.setBounds(1, 1, 700, 700);
JRadioButton rb1 = new JRadioButton("Easy");
JRadioButton rb2 = new JRadioButton("Normal");
JRadioButton rb3 = new JRadioButton("Hard");
JRadioButton rb4 = new JRadioButton("On");
JRadioButton rb5 = new JRadioButton("Off");
JRadioButton rb6 = new JRadioButton("x");
JRadioButton rb7 = new JRadioButton("2x");
JRadioButton rb8 = new JRadioButton("3x");
ButtonGroup bg1 = new ButtonGroup();
ButtonGroup bg2 = new ButtonGroup();
ButtonGroup bg3 = new ButtonGroup();
bg1.add(rb1);
bg1.add(rb2);
bg1.add(rb3);
bg2.add(rb4);
bg2.add(rb5);
bg3.add(rb6);
bg3.add(rb7);
bg3.add(rb8);
optionsPanel.add(screen);
screen.add(difficulty);
screen.add(st);
screen.add(gSpeed);
screen.add(rb1);
screen.add(rb2);
screen.add(rb3);
screen.add(rb4);
screen.add(rb5);
screen.add(rb6);
screen.add(rb7);
screen.add(rb8);
screen.add(music);
screen.add(doneButton);
st.setBounds(200,100,220,40);
difficulty.setBounds(100,150,90,40);
music.setBounds(100,200,90,40);
gSpeed.setBounds(100, 250, 120, 40);
rb1.setBounds(200,150,60,40);
rb2.setBounds(260,150,80,40);
rb3.setBounds(340, 150, 60, 40);
rb4.setBounds(200, 200, 50, 40);
rb5.setBounds(250,200,50,40);
rb6.setBounds(220, 250, 50, 40);
rb7.setBounds(270, 250, 50, 40);
rb8.setBounds(320, 250, 50, 40);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Pong pong = new Pong();
sound("Marimba-music");
mainFrame.dispose();
if(twoPlayer.isSelected()) {
pong.c.isTwoPlayer = true;
}
else {
pong.c.isTwoPlayer = false;
}
}
});
optionsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainFrame.setVisible(false);
optionsFrame.setVisible(true);
}
});
doneButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
optionsFrame.dispose();
Pong pong = new Pong();
if(rb1.isSelected())
{
pong.c.setUp(-10);;
pong.c.setDown(10);
}
else if(rb2.isSelected())
{
pong.c.setUp(-11);
pong.c.setDown(11);
}
else if(rb3.isSelected())
{
pong.c.setUp(-30);
pong.c.setDown(30);
}
if(rb4.isSelected())
{
sound("Marimba-music");
}
else if(rb5.isSelected())
{
soundStop("Marimba-music");
}
if(rb6.isSelected())
{
GamePanel g = new GamePanel();
g.x = 50;
}
else if(rb7.isSelected())
{
GamePanel g = new GamePanel();
g.x = 75;
}
else if(rb8.isSelected())
{
GamePanel g = new GamePanel();
g.x = 100;
System.out.println(g.x);
}
}
});
exitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
mainFrame.dispose();
}
});
}
public void sound(String nm)
{
AudioStream BGM;
try {
InputStream test = new FileInputStream("./" +nm+".wav");
BGM = new AudioStream(test);
AudioPlayer.player.start(BGM);
}
catch(IOException error) {
JOptionPane.showMessageDialog(null, error.getMessage());
}
}
public void soundStop(String nm)
{
AudioStream BGM;
try {
InputStream test = new FileInputStream("./" +nm+".wav");
BGM = new AudioStream(test);
AudioPlayer.player.stop(BGM);
}
catch(IOException error) {
JOptionPane.showMessageDialog(null, error.getMessage());
}
}
}
My Computer.class:
public class Computer
{
private GamePanel field;
private int y = Pong.WINDOW_HEIGHT / 2;
private int yCh = 0;
private int up = -10;
private int down = 10;
private int width = 20;
private int height = 90;
boolean isTwoPlayer = false;
public Computer() {
}
public void update(Ball b) {
if(y + height > Pong.WINDOW_HEIGHT)
{
y = Pong.WINDOW_HEIGHT - height;
}
else if(y < 0)
{
y = 0;
}
if(!isTwoPlayer) {
if(b.getY() < y+height && y >= 0)
{
yCh = up;
}
else if(b.getY() > y && y + height <= Pong.WINDOW_HEIGHT)
{
yCh = down;
}
y = y + yCh;
}
else {
y = y + yCh;
}
}
public void setYPosition(int speed) {
yCh = speed;
}
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRoundRect(450, y, width, height, 10, 10);
}
public int getX() {
return 450;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getUp() {
return up;
}
public int getDown() {
return down;
}
public void setUp(int up) {
this.up = up;
}
public void setDown(int down) {
this.down = down;
}
I don't know how your whole program is structured. But in this piece of code:
doneButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
optionsFrame.dispose();
Pong pong = new Pong();
You create a new instance of Pong class and set the values of the new created instance.
This instance is not used anywhere else. You may need to use a instance of Pong that is already in use, or make other classes use the new created instance.
In my code i generate randoms integer between 0 and 60 and i draw lines based on these.
I just want my lines fit the ordinate vertical line without touching my randoms integer... I guess it's kind of a mathematics problem but i'm really stuck here!
Here's my code first:
Windows.java:
public class Window extends JFrame{
Panel pan = new Panel();
JPanel container, north,south, west;
public JButton ip,print,cancel,start,ok;
JTextArea timeStep;
JLabel legend;
double time=0;
double temperature=0.0;
Timer chrono;
public static void main(String[] args) {
new Window();
}
public Window()
{
System.out.println("je suis là");
this.setSize(1000,400);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setTitle("Assignment2 - CPU temperature");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container = new JPanel(new BorderLayout());
north = new JPanel();
north.setLayout(new BorderLayout());
ip = new JButton ("New");
north.add(ip, BorderLayout.WEST);
print = new JButton ("Print");
north.add(print,BorderLayout.EAST);
JPanel centerPanel = new JPanel();
centerPanel.add(new JLabel("Time Step (in s): "));
timeStep = new JTextArea("0.1",1,5);
centerPanel.add(timeStep);
start = new JButton("OK");
ListenForButton lForButton = new ListenForButton();
start.addActionListener(lForButton);
ip.addActionListener(lForButton);
print.addActionListener(lForButton);
centerPanel.add(start);
north.add(centerPanel, BorderLayout.CENTER);
west = new JPanel();
JLabel temp = new JLabel("°C");
west.add(temp);
container.add(north, BorderLayout.NORTH);
container.add(west,BorderLayout.WEST);
container.add(pan, BorderLayout.CENTER);
this.setContentPane(container);
this.setVisible(true);
}
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==start)
{
time=Double.parseDouble(timeStep.getText());
System.out.println(time);
chrono = new Timer((int)(1000*time),pan);
chrono.start();
}
if(e.getSource()==ip)
{
JPanel options = new JPanel();
JLabel address = new JLabel("IP Address:");
JTextField address_t = new JTextField(15);
JLabel port = new JLabel("Port:");
JTextField port_t = new JTextField(5);
options.add(address);
options.add(address_t);
options.add(port);
options.add(port_t);
int result = JOptionPane.showConfirmDialog(null, options, "Please Enter an IP Address and the port wanted", JOptionPane.OK_CANCEL_OPTION);
if(result==JOptionPane.OK_OPTION)
{
System.out.println(address_t.getText());
System.out.println(port_t.getText());
}
}
if(e.getSource()==print)
{
chrono.stop();
}
}
}
}
Panel.java:
public class Panel extends JPanel implements ActionListener {
int rand;
int lastrand=0;
ArrayList<Integer> randL = new ArrayList<>();
ArrayList<Integer> tL = new ArrayList<>();
int lastT = 0;
Color red = new Color(255,0,0);
Color green = new Color(0,200,0);
Color blue = new Color (0,0,200);
Color yellow = new Color (200,200,0);
int max=0;
int min=0;
int i,k,inc = 0,j;
int total,degr,moyenne;
public Panel()
{
super();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1.8f));
g2.drawLine(20, 20, 20, this.getHeight()-50);
g2.drawLine(20, this.getHeight()-50, this.getWidth()-50, this.getHeight()-50);
g2.drawLine(20, 20, 15, 35);
g2.drawLine(20, 20, 25, 35);
g2.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-45);
g2.drawLine(this.getWidth()-50, this.getHeight()-50, this.getWidth()-65, this.getHeight()-55);
g.drawString("10", 0, this.getHeight()-85);
g.drawString("20", 0, this.getHeight()-125);
g.drawString("30", 0, this.getHeight()-165);
g.drawString("40", 0, this.getHeight()-205);
g.drawString("50", 0, this.getHeight()-245);
g2.drawString("Maximum: ", 20, this.getHeight()-20);
g2.drawString(Integer.toString(max), 80, this.getHeight()-20);
g2.drawString("Minimum: ", 140, this.getHeight()-20);
g2.drawString(Integer.toString(min), 200, this.getHeight()-20);
g2.drawString("Average: ", 260, this.getHeight()-20);
g2.drawString(Integer.toString(moyenne), 320, this.getHeight()-20);
g2.setColor(red);
g2.drawLine(500, this.getHeight()-25, 540, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Maximum", 560, this.getHeight()-20);
g2.setColor(blue);
g2.drawLine(640, this.getHeight()-25, 680, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Minimum", 700, this.getHeight()-20);
g2.setColor(green);
g2.drawLine(780, this.getHeight()-25, 820, this.getHeight()-25);
g2.setColor(new Color(0,0,0));
g2.drawString(": Average", 840, this.getHeight()-20);
if(!randL.isEmpty()){
g2.setColor(red);
g2.drawLine(15, this.getHeight()-50-max, this.getWidth()-50,this.getHeight()-50-max);
g2.setColor(blue);
g2.drawLine(15, this.getHeight()-50-min, this.getWidth()-50,this.getHeight()-50-min);
g2.setColor(green);
g2.drawLine(15, this.getHeight()-50-moyenne, this.getWidth()-50,this.getHeight()-50-moyenne);
}
for(i = 0; i<tL.size(); i++){
int temp = randL.get(i);
int t = tL.get(i);
g2.setColor(new Color(0,0,0));
g2.drawLine(20+t, this.getHeight()-50-temp, 20+t, this.getHeight()-50);
// Ellipse2D circle = new Ellipse2D.Double();
//circle.setFrameFromCenter(20+t, this.getHeight()-50, 20+t+2, this.getHeight()-52);
}
for(j=0;j<5;j++)
{
inc=inc+40;
g2.setColor(new Color(0,0,0));
g2.drawLine(18, this.getHeight()-50-inc, 22, this.getHeight()-50-inc);
}
inc=0;
}
#Override
public void actionPerformed(ActionEvent e) {
rand = (int)(Math.random() * (60));
lastT += 80;
randL.add(rand);
tL.add(lastT);
Object obj = Collections.max(randL);
max = (int) obj;
Object obj2 = Collections.min(randL);
min = (int) obj2;
if(!randL.isEmpty()) {
degr = randL.get(k);
total += degr;
moyenne=total/randL.size();
}
k++;
if(randL.size()>=12)
{
randL.removeAll(randL);
tL.removeAll(tL);
lastT = 0;
k=0;
degr=0;
total=0;
moyenne=0;
}
repaint();
}
}
And here it what i gives me :
Sorry it's a real mess!
Any thoughts ?
Thanks.
You need to stop working with absolute/magical values, and start using the actual values of the component (width/height).
The basic problem is a simple calculation which takes the current value divides it by the maximum value and multiples it by the available width of the allowable area
int length = (value / max) * width;
value / max generates a percentage value of 0-1, which you then use to calculate the percentage of the available width of the area it will want to use.
The following example places a constraint (or margin) on the available viewable area, meaning all the lines need to be painted within that area and not use the entire viewable area of the component
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class DrawLine {
public static void main(String[] args) {
new DrawLine();
}
public DrawLine() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int margin = 20;
int width = getWidth() - (margin * 2);
int height = getHeight() - (margin * 2);
int x = margin;
for (int index = 0; index < 4; index++) {
int y = margin + (int)(((index / 3d) * height));
int length = (int)(((index + 1) / 4d) * width);
g2d.drawLine(x, y, x + length, y);
}
g2d.dispose();
}
}
}
I am making a GUI with Swing that uses an AffineTransform to scale Graphics2D objects painted on a JInternalFrame. The problem is that it is buggy in the current state and I can't figure out why.
Why isn't my code scaling properly? Why do the graphics "jump" to the top of the panel on a resize?
Here is my self contained example:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.util.*;
public class MainPanel extends JFrame implements ActionListener{
private static final double version = 1.0;
private JDesktopPane desktop;
public static RFInternalFrame frame;
private java.util.List<Point> POINT_LIST = Arrays.asList(
//Top Row
new Point(50, 30),
new Point(70, 30),
new Point(90, 30),
new Point(110, 30),
new Point(130, 30),
new Point(150, 30),
new Point(170, 30),
new Point(190, 30),
new Point(210, 30),
new Point(230, 30),
//Circle of Radios
new Point(140, 60),
new Point(120, 80),
new Point(100, 100),
new Point(100, 120),
new Point(120, 140),
new Point(140, 160),
new Point(160, 140),
new Point(180, 120),
new Point(180, 100),
new Point(160, 80));
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
JFrame frame = new MainPanel();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(false);
frame.setVisible(true);
}
public MainPanel() {
super("MainPanel " + version);
//Make the big window be indented 50 pixels from each edge
//of the screen.
int inset = 50;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(inset, inset,
screenSize.width - inset * 7,
screenSize.height - inset * 4);
//Set up the GUI.
desktop = new JDesktopPane(); //a specialized layered pane
desktop.setBackground(Color.DARK_GRAY);
createRFFrame(); //create first RFFrame
createScenarioFrame(); //create ScenarioFrame
setContentPane(desktop);
setJMenuBar(createMenuBar());
//Make dragging a little faster but perhaps uglier.
desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
}
protected JMenuBar createMenuBar() {
JMenuBar menuBar = new JMenuBar();
//Set up the lone menu.
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_D);
menuBar.add(menu);
//Set up the first menu item.
JMenuItem menuItem = new JMenuItem("Add Panel");
menuItem.setMnemonic(KeyEvent.VK_N);
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_N, ActionEvent.ALT_MASK));
menuItem.setActionCommand("new");
menuItem.addActionListener(this);
menu.add(menuItem);
//Set up the second menu item.
menuItem = new JMenuItem("Quit");
menuItem.setMnemonic(KeyEvent.VK_Q);
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_Q, ActionEvent.ALT_MASK));
menuItem.setActionCommand("quit");
menuItem.addActionListener(this);
menu.add(menuItem);
return menuBar;
}
//React to menu selections.
public void actionPerformed(ActionEvent e) {
if ("new".equals(e.getActionCommand())) { //new
createRFFrame();
} else {
//quit
quit();
}
}
/*
* ActivateAllAction activates all radios on the panel, essentially changes the color
* of each ellipse from INACTIVE to ACTIVE
*/
private class ActivateAllAction extends AbstractAction {
public ActivateAllAction(String name) {
super(name);
int mnemonic = (int) name.charAt(1);
putValue(MNEMONIC_KEY, mnemonic);
}
/*
* This will find the selected tab and extract the DrawEllipses instance from it
* Then for the actionPerformed it will call activateAll() from DrawEllipses
*/
#Override
public void actionPerformed(ActionEvent e) {
Component comp = desktop.getSelectedFrame();
if (comp instanceof DrawEllipses){
DrawEllipses desktop = (DrawEllipses) comp;
desktop.activateAll();
}
}
}
/*
* DeactivateAllAction deactivates all radios on the panel, essentially changes the color
* of each ellipse from ACTIVE to INACTIVE
*/
private class DeactivateAllAction extends AbstractAction {
public DeactivateAllAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
/*
* This will find the selected tab and extract the DrawPanel2 instance from it
* Then for the actionPerformed it will call activateAll() from DrawEllipses
*/
#Override
public void actionPerformed(ActionEvent e) {
Component comp = desktop.getSelectedFrame();
if (comp instanceof DrawEllipses){
DrawEllipses desktop = (DrawEllipses) comp;
desktop.deactivateAll();
}
}
}
/*
* Define a JPanel that will hold the activate and deactivate all JButtons
*/
protected JPanel btnPanel() {
JPanel btnPanel = new JPanel();
btnPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
//Set the layout of the frame to a grid bag layout
btnPanel.setLayout(new GridBagLayout());
//Creates constraints variable to hold values to be applied to each aspect of the layout
GridBagConstraints c = new GridBagConstraints();
//Column 1
c.gridx = 0;
btnPanel.add(new JButton(new ActivateAllAction("Activate All")));
//Column 2
c.gridx = 1;
btnPanel.add(new JButton(new DeactivateAllAction("Deactivate All")));
return btnPanel;
}
//not used currently
protected JPanel drawPanel() {
JPanel drawPanel = new JPanel();
drawPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
DrawEllipses drawEllipses = new DrawEllipses(POINT_LIST);
drawPanel.add(drawEllipses);
return drawPanel;
}
//Create a new internal frame.
protected void createRFFrame() {
RFInternalFrame iframe = new RFInternalFrame();
iframe.setLayout(new BorderLayout());
DrawEllipses drawEllipses = new DrawEllipses(POINT_LIST);
iframe.add(drawEllipses);
iframe.add(btnPanel(), BorderLayout.SOUTH);
iframe.setVisible(true);
desktop.add(iframe);
try {
iframe.setSelected(true);
} catch (java.beans.PropertyVetoException e) {}
}
protected void createScenarioFrame() {
ScenarioInternalFrame frame = new ScenarioInternalFrame();
frame.setLayout(new BorderLayout());
frame.setVisible(true);
desktop.add(frame);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {}
}
//Quit the application.
protected void quit() {
System.exit(0);
}
}
#SuppressWarnings("serial")
class DrawEllipses extends JPanel {
private double translateX; //
private double translateY; //
protected static double scale; //
private static final int OVAL_WIDTH = 15;
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points; //
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
public DrawEllipses(java.util.List<Point> points) {
this.points = points; //
translateX = 0; //
translateY = 0; //
scale = 1; //
setOpaque(true); //
setDoubleBuffered(true); //
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
MyMouseAdapter mListener = new MyMouseAdapter();
addMouseListener(mListener);
addMouseMotionListener(mListener);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
AffineTransform tx = new AffineTransform(); //
tx.translate(translateX, translateY); //
tx.scale(scale, scale); //
Graphics2D g2 = (Graphics2D) g;
g2.setTransform(tx);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
for (Ellipse2D ellipse : ellipses) {
if (ellipse.contains(e.getPoint())) {
Color c = ellipseColorMap.get(ellipse);
c = (c == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
ellipseColorMap.put(ellipse, c);
}
}
repaint();
}
}
//Used for button click action to change all ellipses to ACTIVE_COLOR
public void activateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, ACTIVE_COLOR);
}
repaint();
}
//Used for button click action to change all ellipses to INACTIVE_COLOR
public void deactivateAll(){
for (Ellipse2D ellipse : ellipses){
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
repaint();
}
}
class RFInternalFrame extends JInternalFrame implements ComponentListener {
protected static double scale = 1; //
static int openFrameCount = 0;
static final int xOffset = 300, yOffset = 0;
public RFInternalFrame() {
super("RF Panel #" + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
setSize(300, 300);
setMinimumSize(new Dimension(300, 300));
addComponentListener(this);
if (openFrameCount == 1) {
setLocation(0,0);
}
else if (openFrameCount <= 4) {
//Set the window's location.
setLocation(xOffset * (openFrameCount - 1), yOffset * (openFrameCount - 1));
}
else if (openFrameCount == 5) {
setLocation(xOffset - 300, yOffset + 300);
}
else if (openFrameCount == 6) {
setLocation(xOffset + 600, yOffset + 300);
}
}
#Override
public void componentResized(ComponentEvent e) {
String str = "";
if (getWidth() < 300) {
str = "0." + getWidth();
} else {
str = "1." + (getWidth() - 300);
System.out.println(getWidth() - 300);
}
double dou = Double.parseDouble(str);
MainPanel.frame.scale = dou;
repaint();
}
#Override
public void componentMoved(ComponentEvent componentEvent) {
}
#Override
public void componentShown(ComponentEvent componentEvent) {
}
#Override
public void componentHidden(ComponentEvent componentEvent) {
}
}
class ScenarioInternalFrame extends JInternalFrame {
static int openFrameCount = 0;
static final int xOffset = 300, yOffset = 300;
public ScenarioInternalFrame() {
super("Test Scenario" + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
//...Create the GUI and put it in the window...
//...Then set the window size or call pack...
setSize(600, 300);
//Set the window's location.
setLocation(xOffset, yOffset);
}
}
As I understand it, the Graphics object already contains a transform that does a translate to account for the height of the title bar of the internal frame. When you replace the transform you lose this translation so your code is painted at the top of the frame under the title bar.
Don't change properties of the Graphics object passed to the paintComponent() method. Instead create a Graphics2D object you can customize.
When you create a new transform you need to apply the existing transform first before adding new transforms.
The basic structure would be something like:
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g.create();
AffineTransform tx = new AffineTransform(); //
tx.concatenate( g2.getTransform() );
tx.scale(...);
g2.setTransform(tx);
// do custom painting
g2.dispose(); // release Graphics resources
This will just help the painting. You still have several problems (which I can't solve):
Your scale value is never getting updated. You should be adding the ComponentListener to the DrawEllipse panel. You might want to create a setScale() method in the panel that you invoked to set the scale when the panel is resized.
Once you do paint the circles scaled, you MouseListener won't work. The location of all the circles will be different because they have been scaled. You might be able to scale each circle as you iterate through the list of circles.
Also, when you have a question post a proper SSCCE that demonstrates the problem. You have a simple question about using a transform on a panel. So create a frame with a panel and paint a couple of circles on the panel to test the concept.
All the other code is irrelevant to the problem. The menu items are irrelevant, the second internal frame is irrelevant. The MouseListener clicking code is irrelevant. We don't have time to read through 100's of lines of code to understand the question.
Edit:
I changed the order of the code. The tx.scale(...) method must be invoked before setting the transform to the Graphics object.
I my experience, painting on Swing will be done with double buffer. Means that you create the drawing buffer (ie. ImageBuffer). you apply all your drawing logic to the Graphics of the drawing buffer, including transformation, and then finally, draw your buffer into the component's graphics.
This is how I solve your problem...
class DrawEllipses extends JComponent { // I change from JPanel to JComponent, this might not be necessary though...
...
...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// create the drawing buffer.
BufferedImage bi = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics big = bi.getGraphics();
// prepare transform
AffineTransform tx = new AffineTransform(); //
tx.translate(translateX, translateY); //
tx.scale(scale, scale); //
// get the buffer graphics and paint the background white.
Graphics2D g2 = (Graphics2D) big;
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
// apply drawing logic to the Graphics of the buffer
g2.setTransform(tx);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
}
// finally, draw the buffer to the component graphics.
g.drawImage(bi, 0, 0, null);
}
Try it... hope it works and helps.
I have added a ComponentAdapter as ComponentListener to my JDialog, and I want to implement componentResized(ComponentEvent e).
The goal is to maintain the JDialog's ratio, and for my calculation of how to resize it according to the user's action, I would like to know if the user dragged the window's side edge, the window's top/bottom edge, or one of the window's corners.
Is there a way to retrieve that information from the ComponentEvent?
I don't know the answer for my original question (is ther a way to tell the source of the ComponentEvent), so I just store the previous dimensions, and calculate the new size.
If it helps anyone, this is the code I am using. enjoy:
public class ResizableImageView extends JDialog {
BufferedImage img;
Dimension OriginalImgSize;
double imageRatio;
JPanel jp;
JLabel label;
Dimension previousSize;
public ResizableImageView(BufferedImage img) {
...
setResizable(true);
this.img = img;
OriginalImgSize = new Dimension(img.getWidth(), img.getHeight());
imageRatio = (double)img.getWidth() / (double)img.getHeight();
label = new JLabel(new ImageIcon(img));
label.setMinimumSize(OriginalImgSize);
jp = new JPanel();
jp.setBorder(new EmptyBorder(0, 0, 0, 0));
jp.add(label);
setContentPane(jp);
pack();
previousSize = getSize();
addComponentListener(new ComponentAdapter() {
private boolean allreadyResized = true;
private void resize(Image img) {
ImageIcon ico = new ImageIcon(img);
label = new JLabel(ico);
label.setBorder(new EmptyBorder(0, 0, 0, 0));
label.setPreferredSize(new Dimension(img.getWidth(null), img.getHeight(null)));
jp = new JPanel();
jp.setBorder(new EmptyBorder(0, 0, 0, 0));
jp.add(label);
setContentPane(jp);
allreadyResized = true;
pack();
previousSize = getSize();
}
#Override
public void componentResized(ComponentEvent e) {
if (allreadyResized) {
allreadyResized = false;
return;
}
double xChange = (double) Math.abs(getSize().width - previousSize.width);
double yChange = (double) Math.abs(getSize().height - previousSize.height);
if (xChange == 0 && yChange == 0) return;
int height = getSize().height - getInsets().bottom - getInsets().top;
int width = getSize().width - getInsets().left - getInsets().right;
if (height > OriginalImgSize.height
|| width > OriginalImgSize.width) {
resize(img);
return;
}
if (yChange == 0 || xChange/yChange > imageRatio) {
resize(img.getScaledInstance(width, -1, Image.SCALE_SMOOTH));
return;
} else {
resize(img.getScaledInstance(-1, height, Image.SCALE_SMOOTH));
return;
}
}
});
}
}