I have created a GUI via Netbeans Java but whenever I maximize the GUI window the text boxes become misaligned. I used the Netbeans drag and drop function to create the GUI. I was wondering why the text boxes become misaligned whenever I maximize the GUI
It's an issue with the layout.
Read up on using layouts: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
If you are going to use Netbean's GUI builder, run through a tutorial. It'll help you better understand how the builder is to be used. https://netbeans.org/kb/docs/java/quickstart-gui.html
I Understood your problem because I already had the same problem, My advice to you is that you can use the drag and drop of netbeans but before using it first make a panel and in that panel drop all your stuff then using the JFrame Component re sized function just put the panel wherever you want to put it for e.g if you want to center align it.
//if your class is extending JFrame
public static int getWIDTH(){
return WIDTH;
}
public static int getHEIGHT() {
return HEIGHT;
}
private void formComponentResized(java.awt.event.ComponentEvent evt) {
// this is for setting panel in the middle of the JFrame horizontally
int a = getWIDTH();
int b = Panel.getWidth();
a = a/2;
b = b/2;
int centerForX = b - a;
// This is for setting the panel in the middle vertically
int x = getHEIGHT();
int y = Panel.getHeight();
x = x/2;
y = y/2;
int centerForY = x - y;
// Making a 'Point' object and then setting location of the Panel.
Point p = new Point(centerForX , centerForY);
Panel.setLocation(p);
}
Some Keypoints:
1) getWIDTH and getHEIGHT methods will be generated by netbeans write outside all methods but in the class the getwidth and getheight and press ctrl + space and press enter and the getWIDTH and getHEIGHT methods will be generated respectively.
2) the formComponentResized method will be generated by netbeans, just go to design tab and then in the Navigator which is mostly in the bottom left right click on JFrame and then goto events then components and then componentResized.
3) If you have any question don't hesitate to ask, as I have detailed knowledge of this topic.
Related
I'm currently coding a java project and I need a JPanel named board to contain some Tiles that are themselves JPanel, I add them to a layout of appropriate size, but when I add everything with buttons in a grouplayout in a JFrame, only the first Tile is at an appropriate size, and others have ridiculous size like being 1p width and 50p height or 1*1p.
I don't feel like I miss anything, everything is added in the JFrame and added to correct layout, with correct number of rows and lines, and sizes are set to be 50*50p in the Tile class. Here are some code snippets containing the graphic settings, especially the constructors:
Tile.java :
class Case extends JPanel
{
private int _color;
private boolean _star;
private Case _casePere;
private ArrayList<Case> _fils;
private int _x,_y;
public Case(int x, int y)
{
_color = 0;
_star = false;
_casePere = null;
_fils = new ArrayList<Case>();
_x = x;
_y = y;
setPreferredSize(new Dimension(50,50));
setMinimumSize(new Dimension(50,50));
setBackground(Color.WHITE);
}
Board.java :
class Board extends JPanel{
private Case[][] _grid;
private Case[] _starsp1;
private Case[] _starsp2;
// constructeur
public Board(int nbStars, int length){
_grid = new Case[length][length];
_starsp1 = new Case[nbStars];
_starsp2 = new Case[nbStars];
//graphisme
Dimension d = new Dimension(50*length, length*50);
setBackground(Color.BLACK);
setPreferredSize(d);
GridLayout layout = new GridLayout(Constante.length, Constante.length,2 ,2);
setLayout(layout);
for(int y=0; y<length; ++y)
{
for(int x=0; x<length; ++x)
{
_grid[x][y] = new Case(x,y);
add(_grid[x][y]);
}
}
if you want, I can add some snippets of the Window class, but beside the Board, other components don't hav any issues, and it's mainly adding and grouping some components. Here's a screenshot of the output so you can see how the Board's drawing behaves
Edit : I was overriding getX and getY in my Case class overriding JPanel's one, kinda dumb issue again, thanks for the answers
setPreferredSize(d);
Don't set the preferred size of the board. The layout manager of the board will determine the preferred size based on the number of components added to the grid and the size of the largest component added.
Note, (based on the line below) you want a spacing of 2 pixels between each component which your calculation doesn't include. So let the layout manager do its job.
GridLayout layout = new GridLayout(Constante.length, Constante.length,2 ,2);
We don't know what Constante.length is. You pass in a length variable to your class so use that variable.
Also, why does your Case class have so many instance variables? Those variables are never used in the posted code. So maybe you have other methods that are causing problems with the layout. For example don't override getX() or getY() those methods are used by the layout manager.
I'm trying to take a window screenshot to use that as background in the application.
This is my code:
try {
Robot robot = new Robot();
Rectangle captureSize = new Rectangle(new MainWindow().getX(), new MainWindow().getY(), MainWindow.getWIDTH(), MainWindow.getHEIGHT());
RenderManager.backgroundGUIs = robot.createScreenCapture(captureSize);
GUIManager.ThisGui = new GUI("inventory", null, false);
} catch(AWTException e) {
System.err.println("Error taking screenshot!");
}
And these are the MainWindow().getY() and MainWindow().getX() methods:
public int getX() {
return (int) frame.getLocationOnScreen().getX();
}
public int getY() {
return frame.getY();
}
Now... it works fine, but there is a problem. frame.getLocationOnScreen().getX() and frame.getX() return the location with the window border, that hasn't to be in the screensot. Ok, i can manually calculate border size to subtract it, but from Windows 7 to Windows 8, from Windows 8 to Mac, etc. window border changes.
So... is there a method to get frame position or window border size to calculate what i need?
Thank you for your time and your answer!
As simple as this:
x = frame.getRootPane().getX();
As well, you can make all other calculations according to the root pane, just dropping the frame's.
As expected, the root pane is the top-level container inside any Frame/Window/Dialog etc. It includes the menubar too.
Use this
frame.getContentPane().getSize();
Check out the Screen Image class. You can create an image of any component displayed on the frame.
So you could use frame.getRootPane() as the component you want the image of.
Or frame.getContentPane() if you don't want the menu bar. I think this method returns a Container object so you will need to cast is to a JComponent.
int mouseX = MouseInfo.getPointerInfo().getLocation().getX() - frame.getX() - frame.getRootPane().getX();
int mouseY = MouseInfo.getPointerInfo().getLocation().getY() - frame.getY() - frame.getRootPane().getY();
This gives the top right point within the border / tab of a frame
I know there are many questions on here already about positioning components using absolute layout, but they don't seem to answer my questions.
I'm working on creating a Solitaire game in java to better learn GUI components. I seem to understand the various ActionListener classes I'm using, but I'm having trouble positioning components where I want them in the window.
I'm trying to set up the window in a format that resembles the basic solitaire layout (deck, discard pile, 4 suit stacks at the top and 7 solitaire stacks below them). My thought process was that I'd need to use an absolute layout in my JFrame component to manually place the different stack elements where they should go (maybe this isn't the best approach?). In doing so, I've tried using setLocation(x, y), setLocation(Point), setBounds(x, y, width, height), etc and nothing seems to work. I just get a blank window.
Here's an example of my code trying to manually place components in the window:
public class SolitaireTable extends JFrame {
public static final int SUIT_STACK_CNT = 4;
public static final int SOL_STACK_CNT = 7;
public static final Point DECK_POS = new Point(5,5);
public static final Point DISCARD_POS = new Point(73+10, 5); //73 is width of card images and 10 gives it a 5 px border to left and right
public static final Point SUIT_STACK_POS = new Point(DISCARD_POS.x + 73 + 92, 5);
public static final Point SOL_STACK_POS = new Point(DECK_POS.x, DECK_POS.y + 97 + 5); //97 is heigh of card image. 5 gives it a border of 5
public SolitaireTable()
{
setLayout(null);
ImageIcon cardImg = new ImageIcon("images/2c.gif");
Card card1 = new Card(cardImg);
add(card1);
card1.setBounds(50, 50, card1.getWidth(), card1.getHeight());
}
public static void main(String[] args)
{
SolitaireTable table = new SolitaireTable();
table.setTitle("Solitaire");
table.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
table.setVisible(true);
table.setSize(800, 600);
}
}
public class Card extends JComponent {
private ImageIcon img;//current image displayed (either front or back of card)
private Point coords;
private String suit;
private int face; //use ints instead of strings to make descending face pattern calculations easier. 0 = ace, 1= 2, 10 = j, 12 = k, etc
private String color;
private boolean revealed; //whether see face or back of card
private ImageIcon frontImage; //image of card's face side (set in constructor)
public Card(ImageIcon img){
this.img = img;
}
public void moveTo(Point p) {
coords = p;
}
//================================================================= getWidth
public int getWidth() {
return img.getIconWidth();
}
//================================================================ getHeight
public int getHeight() {
return img.getIconHeight();
}
}
I've been scouring the internet for days trying to figure out how to position components in an absolute layout but haven't found much. Any help would be greatly appreciated. Thanks.
You create your Card class with an ImageIcon, but you never paint the Icon anywhere so there is nothing to paint and you get an empty screen.
You need to add painting code to your class. See the section from the Swing tutorial on Custom Painting for more information and working examples.
Or maybe you create a JLabel and add the Icon to the label and then add the label to the component. (Don't forget to set the layout manager of your card component if you use this approach).
Or you could just create a JLabel with the Icon. Then you would extend JLabel, instead of JComponent to add your custom methods.
Are you using Absolute layout ?
Absolute Layout is DEPRECATED ..... Have a look
here
From docs: Absolute layouts are less flexible and harder to maintain than other types of layouts without absolute positioning.
However, if it fits your special purpose, just use it.
You can use RelativeLayouts as described here:
Set the absolute position of a view
I know I am being an idiot and that's why I can't figure it out but I am trying to paint a bunch of rectangles with randoms size and position using paintComponent. I am trying to make sure that all of them are painted within the frame. I am able to do it with the following code (snippet) but I am wondering if there is a better way to do it than me hardcoding numbers into the program. Is there a method that I should take a look at that might be what I'm looking for?
Here's the inner class that overrides the paintComponent() method:
class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
int red = (int)(Math.random()*256);
int blue = (int)(Math.random()*256);
int green = (int)(Math.random()*256);
g.setColor(new Color(red, blue, green));
//The following 4 lines keep the rects within the frame
//The frame is 500,500
int ht = (int)(Math.random()*400);
int wd = (int)(Math.random()*400);
int x = (int)(Math.random()*100);
int y = (int)(Math.random()*100);
g.fillRect(x,y,ht,wd);
}
}
You should base your co-ordinates & sizes on the DrawPanel component size. Also using Random.nextInt instead of Math.random() will make it easier to keep within range based on the current size of the panel:
Random random = new Random();
int ht = random.nextInt(getHeight());
int wd = random.nextInt(getWidth());
int x = random.nextInt(getWidth() - wd);
int y = random.nextInt(getHeight() - ht);
I am wondering if there is a better way to do it than me hardcoding numbers into the program.
Yes there is
call getSize() on the enclosing JPanel, the DrawPanel, so you can see the actual boundaries of the component that is being drawn upon. (edit: or getWidth() and getHeight() as recommended by Lucas -- 1+ to his answer!).
Also, you will usually want to call the super's paintComponent(...) method within the child's override.
Also you will usually want to do your randomization elsewhere, such as in the DrawPanel's constructor so as not to change your rectangles each time you re-size the GUI.
There is a method to get the length and width of the panel you are working in.
getHeight();
getWidth();
These will return the current size of the JPanel you are working in, meaning if you resize the window it'll actually still draw them inside.
http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#getWidth()
Is there anything obvious wrong with this line of code? I want rectangle to stay centered regardless the size of the window. But this donĀ“t work for some reason, the rectangle stays the same place.
public void run() {
setSize(800, 800);
createEntireFigure();
}
private void createEntireFigure(){
int centerOfWindowWidth = getWidth() / 2;
int centerOfWindowHeight = getHeight() / 2;
GRectWithGLabel ("A String",centerOfWindowWidth, centerOfWindowHeight);
}
Your rectangle size code is only called on rectangle creation, and so it makes sense that the rectangle's position will not change if the GUI is re-sized. You need to somehow listen for size changes in your GUI and call code to re-position the rectangle then for this to work. What graphics library are you using?