When i setSize of a jLabel, normally it grows towards bottom. How can i increase the height in positive y direction ?
After pressing init
Current Result
Expected result
My source code
private void initActionPerformed(java.awt.event.ActionEvent evt) {
int p = Integer.parseInt(abc[0].getText());
int q = Integer.parseInt(abc[1].getText());
int r = Integer.parseInt(abc[2].getText());
int s = Integer.parseInt(abc[3].getText());
int t = Integer.parseInt(abc[4].getText());
one.setSize(20, p*10 );
one.setBackground(Color.decode("#03A9F4"));
two.setSize(20, q*10 );
two.setBackground(Color.decode("#03A9F4"));
three.setSize(20, r*10 );
three.setBackground(Color.decode("#03A9F4"));
four.setSize(20, s*10 );
four.setBackground(Color.decode("#03A9F4"));
five.setSize(20, t*10 );
five.setBackground(Color.decode("#03A9F4"));
}
one,two,three are the label names.
abc is an array containing all the labels
You're finding out that Java considers positive y direction graphics to be down, which is in keeping with how computer monitors see y direction. Solutions include:
Figure out a maximum size, and subtract your y height from it to figure out where to start your JLabel.
Even better, don't use JLabels but draw within a JPanel's paintComponent, using the same calculations as above.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
#SuppressWarnings("serial")
public class GraphicsEg extends JPanel {
private static final int DATA_COLUMNS = 5;
private List<JSlider> sliders = new ArrayList<>();
private DrawPanel drawPanel = new DrawPanel(DATA_COLUMNS);
public GraphicsEg() {
JPanel sliderPanel = new JPanel(new GridLayout(1, 0, 5, 5));
SliderListener sliderListener = new SliderListener();
for (int i = 0; i < DATA_COLUMNS; i++) {
JSlider slider = new JSlider(0, 100, 50);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setPaintTrack(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setOrientation(SwingConstants.VERTICAL);
slider.addChangeListener(sliderListener);
sliders.add(slider);
sliderPanel.add(slider);
}
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
add(drawPanel, BorderLayout.CENTER);
add(sliderPanel, BorderLayout.PAGE_END);
sliderValuesIntoDrawPanel();
}
private void sliderValuesIntoDrawPanel() {
int[] data = new int[DATA_COLUMNS];
for (int i = 0; i < data.length; i++) {
data[i] = sliders.get(i).getValue();
}
drawPanel.setData(data);
}
private class SliderListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
sliderValuesIntoDrawPanel();
}
}
private static void createAndShowGui() {
GraphicsEg mainPanel = new GraphicsEg();
JFrame frame = new JFrame("GraphicsEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class DrawPanel extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 400;
private static final int PAD = 20;
private static final Color BORDER_COLOR = Color.BLUE;
private static final Color COLUMN_COLOR = Color.RED;
private static final double RELATIVE_COL_WIDTH = 2.0 / 3.0;
private int dataColumns = 0;
private int[] data;
public DrawPanel(int dataColumns) {
this.dataColumns = dataColumns;
data = new int[dataColumns];
setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
}
public void setData(int[] data) {
this.data = data;
repaint();
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < data.length; i++) {
drawColumn(g, i, data[i]);
}
}
private void drawColumn(Graphics g, int index, int columnHeight) {
g.setColor(COLUMN_COLOR);
int width = (int) (RELATIVE_COL_WIDTH * (PREF_W - 2 * PAD) / dataColumns);
int x = PAD + (index * (PREF_W - 2 * PAD)) / dataColumns;
int height = (columnHeight * (PREF_H - 2 * PAD)) / 100;
int y = PREF_H - PAD - height;
g.fillRect(x, y, width, height);
}
}
Related
When a Grid Object is instantiated, a JFrame and JPanel are created. Lines are drawn upon the JPanel to create a square grid. Ideally, the grid will scale if the window is resized.
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ComponentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentAdapter;
public class Grid {
private int lines;
private int space;
public static final int DEFAULT_LINES = 5;
public static final int DEFAULT_SPACE = 5;
private JPanel panel = new GridPanel();
private JFrame frame;
public Grid(String name, int lines, int space) {
this.frame = new JFrame(name);
this.lines = lines;
this.space = space;
this.frame.setSize((lines * space), (lines * space));
}
private class GridPanel extends JPanel {
private int start = 0;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int end = (lines * space);
g.setColor(Color.BLACK);
for (int i = 0; i < lines; i++) {
int crawl = (space * i);
g.drawLine(start, crawl, end, crawl);
g.drawLine(crawl, start, crawl, end);
}
}
}
/*private class GridHandler extends ComponentAdapter {
#Override
public void componentResized(ComponentEvent e) {
super.componentResized(e);
setSpace();
frame.repaint();
frame.revalidate();
}
}*/
public void setSpace() {
space = (frame.getSize().width * frame.getSize().height) / lines;
}
public void run() {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(panel);
//frame.addComponentListener(new GridHandler());
frame.setVisible(true);
}
}
public class Run {
public static final int ONE_LINES = 15;
public static final int ONE_SPACE = 20;
public static final int TWO_LINES = 35;
public static final int TWO_SPACE = 16;
public static void main(String[] args) {
Grid grid1 = new Grid("Grid One", ONE_LINES, ONE_SPACE);
Grid grid2 = new Grid("Grid Two", TWO_LINES, TWO_SPACE);
grid1.run();
grid2.run();
}
}
These are the only two files being used. The Handler is currently commented out, and the code does what is expected. Two windows with grids are created. However, when the handler is implemented, the grid no longer shows up. What is the correct implementation for the handler?
For anyone that cares, this is a viable solution. As it turns out, a componentResized Event Handler is not needed. The paintComponent is automatically executed when the JFrame is re-sized.
The following code creates two separate JFrames. Each JFrame contains a single JPanel. A unique square grid is drawn on the JPanel. If the JFrame is re-sized, the grid will also re-size (while still remaining square).
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
public class Grid extends JPanel {
private static final int DEFAULT_COUNT = 10;
private static final int DEFAULT_SIZE = 100;
private int count;
public Grid(int count, int size) {
if (size < 1) {
this.count = DEFAULT_COUNT;
this.setPreferredSize(new Dimension(DEFAULT_SIZE, DEFAULT_SIZE));
} else {
this.count = count;
this.setPreferredSize(new Dimension(size, size));
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics = (Graphics2D) g;
graphics.setColor(Color.black);
Dimension size = getSize();
int w = size.width;
int h = size.height;
if (w > h) {
w = h;
} else if (h > w) {
h = w;
}
int spaceWidth = (int)((double)w / count);
int spaceHeight = (int)((double)h / count);
for (int row = 0; row <= count; row++) {
int y = (row * spaceHeight);
int x = (row * spaceWidth);
graphics.drawLine(0, y, (spaceWidth * count), y);
graphics.drawLine(x, 0, x, (spaceHeight * count));
}
}
}
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
public class Test {
public static final int COUNT_1 = (-5);
public static final int SIZE_1 = 4;
public static final int COUNT_2 = 35;
public static final int SIZE_2 = 16;
public static void main(String[] args) {
int area1 = COUNT_1 * SIZE_1;
int area2 = COUNT_2 * SIZE_2;
Grid grid = new Grid(COUNT_1, area1);
JFrame frame = new JFrame("Grid");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(grid);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Grid grid2 = new Grid(COUNT_2, area2);
JFrame frame2 = new JFrame("Grid");
frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame2.add(grid2);
frame2.pack();
frame2.setLocationRelativeTo(null);
frame2.setVisible(true);
}
}
I'm trying to code a simple Pong and I have the background panel which contains a Bar panel. So of course I need to be able to place the bar on the size and move it vertically at request. Now I'm just trying to put it in a starting position. If I don't disable the layout the bar gets placed in the top center regardless of location setting, but if I disable the layout and set location it just doesn't show up. I'm not sure what I missing. Here is a code snippet if it can be relevant:
public PongPanel() {
setLayout(null);
setPreferredSize(SIZE);
setBackground(Color.BLACK);
player_one_bar = new Bar();
add(player_one_bar);
player_one_bar.setLocation(10, getSize().height/2-3);
}
If you set the layout manager as null you'll have to specify the exact coordinates of the panel, meaning something like -
setBounds(10, 10, 20, 100);
Will put the panel at location (10,10) with Width of 20 and Height of 100.
If by "bar" you mean Pong game paddle, then it shouldn't be a component at all but rather a logical entity that represents a position, which is visually represented by a sprite that gets drawn in the JPanel's paintComponent method.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class PongPaddle extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 500;
private static final int RECT_X = 20;
private static final int RECT_W = 10;
private static final int RECT_H = 60;
private static final int STARTING_Y = (PREF_H - RECT_H) / 2;
private static final int TIMER_DELAY = 15;
private static final int DELTA_PADDLE = 3;
private boolean paddle1GoingDown = true;
private boolean paddle2GoingDown = false;
private Rectangle paddle1 = new Rectangle(RECT_X, STARTING_Y, RECT_W, RECT_H);
private Rectangle paddle2 = new Rectangle(PREF_W - RECT_X - RECT_W,
STARTING_Y, RECT_W, RECT_H);
public PongPaddle() {
setBackground(Color.black);
new Timer(TIMER_DELAY, new TimerListener()).start();
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int deltaPaddle1 = paddle1GoingDown ? 1 : -1;
deltaPaddle1 *= DELTA_PADDLE;
int x = paddle1.getLocation().x;
int y = paddle1.getLocation().y + deltaPaddle1;
if (y + RECT_H >= PREF_H) {
paddle1GoingDown = false;
}
if (y <= 0) {
paddle1GoingDown = true;
}
paddle1.setLocation(x, y);
int deltaPaddle2 = paddle2GoingDown ? 1 : -1;
deltaPaddle2 *= DELTA_PADDLE;
x = paddle2.getLocation().x;
y = paddle2.getLocation().y + deltaPaddle2;
if (y + RECT_H >= PREF_H) {
paddle2GoingDown = false;
}
if (y <= 0) {
paddle2GoingDown = true;
}
paddle2.setLocation(x, y);
repaint();
if (!PongPaddle.this.isShowing()) {
((Timer) e.getSource()).stop();
}
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.white);
if (paddle1 != null) {
g2.fill(paddle1);
}
if (paddle2 != null) {
g2.fill(paddle2);
}
}
private static void createAndShowGui() {
PongPaddle mainPanel = new PongPaddle();
JFrame frame = new JFrame("PongPaddle");
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();
}
});
}
}
I want to replace a panel by another one (all of them has transparent section).
The code is as followed:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PhotoFrame extends JFrame {
public class PhotosDisplayPanel extends JPanel {
private static final long serialVersionUID = 1L;
private String[] imgsLink = null;
private long delay = 1000;
private long period = 1000;
private int curIdx = 0;
private PhotoDisplayPanel currentPhoto = null;
public PhotosDisplayPanel(String[] imgsLink) {
super();
this.imgsLink = imgsLink;
setBackground(new Color(0, 0, 0, 0));
setLayout(new GridLayout(1, 1));
currentPhoto = new PhotoDisplayPanel(imgsLink[curIdx]);
add(currentPhoto);
}
public void start() {
if (imgsLink == null) {
return;
}
curIdx = -1;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
curIdx++;
if (curIdx >= imgsLink.length) {
curIdx = 0;
}
displayNextImage();
}
}, delay, period);
}
protected void displayNextImage() {
if (currentPhoto != null) {
remove(currentPhoto);
}
revalidate();
repaint();
currentPhoto = new PhotoDisplayPanel(imgsLink[curIdx]);
add(currentPhoto);
revalidate();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
public class PhotoDisplayPanel extends JPanel {
private static final long serialVersionUID = 1L;
private String imgLink;
public PhotoDisplayPanel(String imgLink) {
super();
this.imgLink = imgLink;
}
#Override
protected void paintComponent(Graphics g) {
if (imgLink != null && !imgLink.equals("")) {
System.out.println("Draw image");
// get dimension of the panel
int pWidth = getWidth();
int pHeight = getHeight();
g.setColor(new Color(255, 0, 0, 50));
g.fillRect(0, 0, pWidth, pHeight);
Image img = new ImageIcon(imgLink).getImage();
// Calculate positions and dimensions
int imgWidth = img.getWidth(this);
int imgHeight = img.getHeight(this);
int iwidth = 0;
int iheight = 0;
if (imgWidth / imgHeight > pWidth / pHeight) {
iwidth = pWidth;
iheight = imgHeight * pWidth / imgWidth;
} else {
iheight = pHeight;
iwidth = imgWidth * pHeight / imgHeight;
}
int ix = (pWidth - iwidth) / 2;
int iy = (pHeight - iheight) / 2;
// Fill the picture to the panel
g.drawImage(img, ix, iy, iwidth, iheight, this);
} else {
super.paintComponent(g);
}
}
}
private static final long serialVersionUID = 1L;
private static final int defaultWidth = 650;
private static final int defaultHeight = 400;
private int width = defaultWidth;
private int height = defaultHeight;
private PhotosDisplayPanel photoPanel; // is view panel which display
// input and output
private String[] imgsLink;
public PhotoFrame() {
initialize();
imgsLink = new String[] { "background.png", "screenShot.jpg" };
createControls();
}
private void createControls() {
setLayout(new GridLayout(0, 1));
photoPanel = new PhotosDisplayPanel(imgsLink);
add(photoPanel);
photoPanel.start();
}
private void initialize() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
setTitle("PhotosFrame");
setAlwaysOnTop(false);
setBackground(Color.CYAN);
setLayout(new GridLayout(1, 1));
setContentPane(new JLabel(new ImageIcon("blue_sunset.jpg")));
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new PhotoFrame().setVisible(true);
}
});
}
}
In which, currentPhoto is a panel with transparent background. However, the image of the old panel is not cleaned totally, I can see the old one under the new one. Is there any way to clear the image of old panel comprehensively?
Thanks
However, the image of the old panel is not cleaned totally,
Check out Backgrounds With Transparency for the probable cause and a couple of solutions.
Basically when using transparent backgrounds Swing does not know that is need to repaint the background so you need to force the repainting.
I have a 2d array of Grids (JPanels) that are added to another JPanel using the GridLayout. That JPanel is added to the JFrame. Whenever a click happens on the JFrame I'm attempting to take the Point of the click and determine if any of those Grids in the 2d array contain that Point.
I'm attempting to do this inside frame.addMouseListener...
I know the frame is registering the mouse clicks. For some reason the Grids don't register that they should be containing that Point. Can anyone explain this? if(theView[i][j].contains(me.getPoint())){ This is the line of code that seems to be failing me.
I originally attempted to have the Grids know when they were clicked on so I wouldn't have to coordinate between the frame and grids, but I couldn't get that to work.
Here's the level designer.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import javax.swing.*;
public class LevelDesigner extends JPanel implements ButtonListener{
private final int SIZE = 12;
private int [][] thePit;
private Grid [][] theView;
private ButtonPanel bp;
public static int val;
private int rows, cols;
private JPanel gridPanel;
private JFrame frame;
public LevelDesigner(int r, int c){
frame = new JFrame();
int h = 10, w = 10;
setVisible(true);
setLayout(new BorderLayout());
setBackground(Color.BLUE);
rows = r;
cols = c;
thePit = new int[r][c];
theView = new Grid[r][c];
gridPanel = new JPanel();
gridPanel.setVisible(true);
gridPanel.setBackground(Color.BLACK);
gridPanel.setPreferredSize(getMaximumSize());
GridLayout gridLayout = new GridLayout();
gridLayout.setColumns(cols);
gridLayout.setRows(rows);
gridPanel.setLayout(gridLayout);
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
theView[i][j] = new Grid(i, j, SIZE, this);
gridPanel.add(theView[i][j]);
}
}
String test [] = {"0", "1","2","3","4","save"};
bp = new ButtonPanel(test, this);
this.add(bp, BorderLayout.SOUTH);
this.add(gridPanel, BorderLayout.CENTER);
frame.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me) {
for(int i = 0; i < rows; ++i){
for(int j = 0; j < cols; ++j){
if(theView[i][j].contains(me.getPoint())){
theView[i][j].actionPerformed(null);
return;
}
}
}
}
});
frame.setVisible(true);
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
frame.setTitle("Epic Crawl - Main Menu");
frame.pack();
frame.setLocationRelativeTo(null);
frame.repaint();
frame.add(this);
}
public String toString(){
int noRows = thePit.length;
int noColumns = thePit[0].length;
String s="";
for (int r=0;r<noRows;r++){
for (int c=0;c<noColumns;c++){
s=s + thePit[r][c] + " ";
}
s=s+"\n";
}
return(s);
}
public void notify( int i, int j){
thePit[i][j] = val;
}
public void print(){
final JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new java.io.File("."));
int returnVal = fc.showSaveDialog( null);
if( returnVal == JFileChooser.APPROVE_OPTION ){
try{
PrintWriter p = new PrintWriter(
new File( fc.getSelectedFile().getName() ) );
System.out.println(" printing");
p.println( this );
p.close();
}
catch( Exception e){
System.out.println("ERROR: file not saved");
}
}
}
public void buttonPressed(String buttonLabel, int id){
if(id == 5)
print();
else
val = id;
}
public void buttonReleased( String buttonLabel, int buttonId ){}
public void buttonClicked( String buttonLabel, int buttonId ){}
public static void main(String arg[]){
LevelDesigner levelDesigner = new LevelDesigner(4, 4);
}
}
And here is the Grid.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Grid extends JPanel implements ActionListener{
LevelDesigner grid;
int myI, myJ;
private String[] imageNames = {"dirt.png", "grass.png", "Door.png", "woodfloor.png", "32x32WoodFloor.png"};
BufferedImage gridImage;
private String imagePath;
public Grid(int i, int j, int size, LevelDesigner m){
imagePath = "";
grid = m;
myI = i;
myJ = j;
setBackground(Color.RED);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent ae){
grid.notify(myI, myJ);
imagePath = "Images/" + imageNames[LevelDesigner.val];
gridImage = null;
InputStream input = this.getClass().getClassLoader().getResourceAsStream(imagePath);
try{
gridImage = ImageIO.read(input);
}catch(Exception e){System.err.println("Failed to load image");}
}
public void paintComponent(Graphics g){
super.paintComponent(g); // Important to call super class method
g.clearRect(0, 0, getWidth(), getHeight()); // Clear the board
g.drawImage(gridImage, 0, 0, getWidth(), getHeight(), null);
}
}
The contains method checks if the Point is within the boundaries of the JPanel but using a coordinate system relative to the JPanel. Instead consider using findComponentAt(Point p).
For example:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class TestMouseListener {
private static final int SIDE_COUNT = 4;
private JPanel mainPanel = new JPanel();
private MyGridCell[][] grid = new MyGridCell[SIDE_COUNT][SIDE_COUNT];
public TestMouseListener() {
mainPanel.setLayout(new GridLayout(SIDE_COUNT, SIDE_COUNT));
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new MyGridCell();
mainPanel.add(grid[i][j].getMainComponent());
}
}
mainPanel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Component c = mainPanel.findComponentAt(p);
for (MyGridCell[] gridRow : grid) {
for (MyGridCell myGridCell : gridRow) {
if (c == myGridCell.getMainComponent()) {
myGridCell.setLabelText("Pressed!");
} else {
myGridCell.setLabelText("");
}
}
}
}
});
}
public Component getMainComponent() {
return mainPanel;
}
private static void createAndShowGui() {
TestMouseListener mainPanel = new TestMouseListener();
JFrame frame = new JFrame("TestMouseListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyGridCell {
private static final int PREF_W = 200;
private static final int PREF_H = PREF_W;
#SuppressWarnings("serial")
private JPanel mainPanel = new JPanel() {
public Dimension getPreferredSize() {
return MyGridCell.this.getPreferredSize();
};
};
private JLabel label = new JLabel();
public MyGridCell() {
mainPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.setLayout(new GridBagLayout());
mainPanel.add(label);
}
public Component getMainComponent() {
return mainPanel;
}
public void setLabelText(String text) {
label.setText(text);
}
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
Component#contains "Checks whether this component "contains" the specified point, where the point's x and y coordinates are defined to be relative to the coordinate system of this component"
This means that the contains will only return true if the Point is within the bounds of 0 x 0 x width x height.
So if the component is position at 400x200 and is sized at 200x200 (for example). When you click within in, the mouse point will be between 400x200 and 600x400, which is actually out side of the relative position of the component (200x200) - confused yet...
Basically, you either need to convert the click point to a relative coordinate within the context of the component you are checking...
Point p = SwingUtilities.convertPoint(frame, me.getPoint(), theView[i][j])
if (theView[i][j].contains(p)) {...
Or use the components Rectangle bounds...
if (theView[i][j].getBounds().contains(me.getPoint())) {...
So, remember, mouse events are relative to the component that they were generated for
I need help with drawing the grids to the GUI as well as the program later letting me change the colour of the boxes drawn. I know i will have to use paintComponent(Graphics g), but i have no idea how or where.
So here is a copy of the code i have got so far ( even though i have been told it can be quite daunting just being given code i think it is the best way for people to help and not just do it for me). From the top it sets values, creates the GUI, calls the GUI, fills a 2d array with boxes( i think). Then in the Boxes class setting values the boxes class will need, then the start of how to draw them (didn't know how to work it out), then some seta methods for the x and y coordinates.
what i would like you to do is show how to have the boxes be drawn to the Jpanel, to make a grid and then to show me how to change the colour to different shades of blue, depending on a external value.
import java.awt.*;
import java.awt.Graphics;
import java.util.*;
import javax.swing.*;
public class NewGrid {
Boxes[][] Boxs;
int BoxesX;
int BoxesY;
NewGrid() {
buildtheGUI();
}
JFrame frame = new JFrame();
JPanel panel = new JPanel();
public void buildtheGUI() {
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
}
public static void main(String[] args) {
new NewGrid();
}
public void addboxes() {
Boxs = new Boxes[panel.getWidth() / 10][panel.getHeight() / 10];
for (int i = 0; i < panel.getWidth() / 10; i++) {
for (int j = 0; j < panel.getHeight() / 10; j++) {
Boxs[i][j] = new Boxes();
Boxs[i][j].setx(i * (panel.getWidth() / 10));
Boxs[i][j].sety(j * (panel.getHeight() / 10));
Boxs[i][j].draw(null);
}
}
}
}
public class Boxes extends JPanel {
int x;
int y;
int width = 10;
int hieight = 10;
Color colour = Color.BLACK;
public void draw(Graphics g) {
g.setColor(colour);
g.fillRect(x, y, width, hieight);
}
public void setx(int i ){
x = i;
}
public void sety(int i ){
y = i;
}
}
I can't comment something, to try to make things easier,
I code there box.putClientProperty(unique_identifier, value_for_identifier), you can to multiple this method as you want
from every Swing Listener you can to get this and proper coordinated defined in putClientProperty
.
JComponent comp = event.getComponent();
String strRow = (String) comp.getClientProperty("row");
String strColumn = (String) comp.getClientProperty("column");
simple code
import java.awt.*;
import java.awt.Graphics;
import java.util.*;
import javax.swing.*;
public class NewGrid {
private int row = 10;
private int column = 10;
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private NewGrid() {
addboxes();
panel.setLayout(new GridLayout(row, column));
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private void addboxes() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
Boxes box = new Boxes();
box.putClientProperty("row", row);
box.putClientProperty("column", column);
panel.add(box);
}
}
}
public static void main(String[] args) {
Runnable doRun = new Runnable() {
#Override
public void run() {
new NewGrid();
}
};
SwingUtilities.invokeLater(doRun);
}
}
class Boxes extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(20, 20);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(20, 20);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(20, 20);
}
#Override
public void paintComponent(Graphics g) {
int margin = 2;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2,
dim.height - margin * 2);
}
}