I am making a JFrame with the size of 500x500 pixels.
I make a blue background and add a red square in the right-bottom corner from (490,490) to (500,500).
Image:
I don't see the red square on the screen.
I switched the frame from not resizable to resizable and if I make the window larger the red dot is there.
Is the frame size the same as application's window size?
How can I make the application's window to be the exactly 500x500?
Your content pane should override the getPreferredSize() method, returning a Dimension object with width and height of 500 pixels:
public class MyContentPane extends JPanel {
private Dimension dimension;
public MyContentPane() {
this.dimension = new Dimension(500, 500);
}
#Override
public Dimension getPreferredSize() {
return this.dimension;
}
}
// How to use your new class
SwingUtils.invokeLater(() -> {
JFrame frame = new JFrame("Title");
frame.setContentPane(new MyContentPane());
frame.pack();
frame.setVisible(true);
});
The size of your JFrame will be calculated by Swing by taking in consideration the preferred size of the components inside it.
The frame is the size of the entire window, including the title bar required by the OS. When drawing things in the JPanel in the JFrame, the (0, 0) coordinate is in the top left corner if the JPanel, which begins just below the title bar. It sounds like your title bar is taller than 10 pixels, so 490 as a y component is actually off the window, since the visible height of the JPanel is windowHeight - titleBarHeight.
Should user the following
#Override
PreferedSize()
Remember preferedSize method is method of the super class JFrame.
this may be useful for you?
JPanel aa = new JPanel(new GridBagLayout());
aa.setMaximumSize(new Dimension(500,500));
aa.setMinimumSize(new Dimension(490,490));
aa.setBorder(BorderFactory.createLineBorder(Color.black));
Related
I'm learning flow layout from Head First Java and I'm trying to have buttons wrap around as it says a Flow Layout should (left to right, top to bottom).
import javax.swing.*;
import java.awt.*;
public class Flow {
public static void main(String[] args) {
Flow gui = new Flow();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton buttonOne = new JButton("hello");
JButton buttonTwo = new JButton("this is");
JButton buttowThree = new JButton("woody");
panel.add(buttonOne);
panel.add(buttonTwo);
panel.add(buttonThree);
frame.getContentPane().add(BorderLayout.EAST, panel);
frame.setSize(200,200);
frame.setVisible(true);
}
}
However, when setting the panel on the EAST region of the frame, the buttons go off the screen and don't wrap around. If I set the panel on the NORTH or SOUTH region, I only see two buttons. If I set the panel on the CENTER region, they DO wrap and can see all of them clearly. Why is this?
If you're adding a component to a BorderLayout frame, the East and West regions will let the component get its preferred width. Since the panel contains three buttons and places them side by side, the preferred width of the panel is that of the three buttons side by side. Therefore, it is going "off-the-screen" since that is the preferred width. If you were to a button on to the frame on the EAST region instead and fill it up with enough text, the same would happen. The CENTER region gets whatever is left that the other regions haven't taken up already. Since that is the policy of the CENTER region, the panel does NOT get its preferred width or height, therefore forcing the components of the panel to wrap.
As far as the NORTH and SOUTH regions go, the panel will get its preferred height which is the height of the tallest component (in the example all buttons are the same height). Therefore it sees no reason to wrap. The panel however, DOESN'T get its preferred width. Therefore the buttons are "cut off" since the max width the panel can have is that of the frame. You will notice as the frame resizes, the buttons appear on the screen as space is made available on the panel.
I use a JLabel to view an image in a JFrame. I load it from a file with an ImageIcon.
JFrame frame = new JFrame(String);
frame.setLocationByPlatform(true);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel cpu = new JLabel(new ImageIcon(String));
cpu.setLocation(20, 20);
cpu.setSize(20, 460);
frame.add(cpu);
frame.setVisible(true);
I can't set location and size of the JLabel because it is done automatically.
I have to manually set these values because I want to truncate the image (vertical progress bar).
One way is to just paint the image:
final ImageIcon icon = new ImageIcon(path);
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(icon.getImage(), 0, 0, getWidth(), getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
};
frame.add(panel);
The getWidth() and getHeight() in drawImage will force the image to stretch the size of the panel. Also the getPreferredSize() will give a size to the panel.
If want the panel to stay that size, then make sure it's parent container has a layout manager that will respect preferred sizes, like FlowLayout or GridBagLayout. If you want the panel to be stretched, the make sure it's parent container has a layout manager that disregards the preferred size, like BorderLayout or GridLayout
See Performing Custom Painting for more info on painting.
See Laying Out Components Within a Container to learn more about layout managers (which you should be using). Also see Why is it frowned upon to use a null layout in SWING? and What's wrong with the Null Layout in Java?
The size of your original is (58 x 510). If you want to display the image at a fixed size of 20 x 420, then you should scale your image to that size to you don't truncate any of the image. One way to do that is to use the Image.getScaledImage(...) method. Then you just add the scaled image to the label.
If you want to position your label (20, 20) from the top left of the panel, then you can add an EmptyBorder to the panel or the label.
Use the features of Swing.
Edit:
I want to truncate the image
Read your Image into a BufferedImage. Then you can use the getSubImage(...) method to get an image any size you want. Then you can use the sub image to create your ImageIcon and add it to a label.
The LayoutManager is auto-sizing your components, not allowing you to resize manually.
If you want to get away from this, you can turn off the LayoutManager.
frame.setLayout(null);
Please note that you should not use the null layout.
I am new to Swing. I am building a JFrame with a JScrollPane inside it using Eclipse IDE. Inside of the JScrollPane is a JPanel in Border Layout. I tried to add a JButton (called "submitAnswers") to the JFrame using the code below, but for some reason the button only appears at the end of the frame on my computer, but not on other computers (my friend tried it on his Mac and I tried it on a separate Windows OS like mine). Some proposed solutions that I have tried and from other sites that have not worked include:
Use the pack() method. Reason: since the preferred size of the JPanel is much longer in height than the JFrame (hence I employed a JScrollPane), packing the JFrame only causes the text to be not visible on the desktop.
Place button on content JPanel. Reason: I don't know. It just wouldn't appear on another desktop computer or my friend's mac computer.
Use BorderLayout.SOUTH instead of BorderLayout.PAGE_END. Reason: There was absolutely no change. The button would still be visible on my computer, but invisible on others.
Place button directly on JFrame. Reason: I don't know.
In addition, my JFrame is nested within a static method; hence, I've only included the relevant code for the specific method I'm having issues with.
Has anyone had this issue before? I would really appreciate your insight.
Code:
public static void createTestPage() {
JFrame testFrame = new JFrame("testing...1,2,3");
//Customizes icon to replace java icon
try {
testFrame.setIconImage(ImageIO.read(new File("src/icon.png")));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//Centers location of introFrame to center of desktop
Dimension screenDimensions = Toolkit.getDefaultToolkit().getScreenSize();
testFrame.setLocation(screenDimensions.width / 16,screenDimensions.height / 14);
//Size and display the introFrame.
Insets insets = testFrame.getInsets();
//Format size of screen itself
testFrame.setSize(1200 + insets.left + insets.right,
400 + insets.top + 250 + insets.bottom);
//Temporarily set screen so that it cannot be resized
testFrame.setResizable(false);
//Set background color of testFrame
testFrame.getContentPane().setBackground(new Color(75, 0, 130));
testFrame.setLayout(new BorderLayout());
//Set layout of testFrame
testFrame.setLayout(new BorderLayout(10, 1));
//Test content
JPanel testContentPanel = new JPanel();
testContentPanel.setBackground(new Color(75, 0, 130));
testContentPanel.setSize(new Dimension(900,2060));
testContentPanel.setPreferredSize(new Dimension(900, 2060));
//Test content pane layout
testContentPanel.setLayout(new BoxLayout(testContentPanel, BoxLayout.PAGE_AXIS));
//Create panel to hold instructions text
JPanel instructionsPanel = new JPanel();
instructionsPanel.setBackground(new Color(75, 0, 130));
instructionsPanel.setLayout(new BorderLayout(10,1));
//Create JPanel for submit answers button
JPanel submitAnswersPanel = new JPanel(new BorderLayout());
submitAnswersPanel.setBackground(new Color(75, 0, 130));
submitAnswersPanel.setVisible(true);
//Create button to submit personality test answers
JButton submitAnswers = new JButton("Submit Answers");
submitAnswers.setVisible(true);
submitAnswers.setBorder(new EmptyBorder(10, 400, 10, 400));
//Add submitAnswers button to panel
submitAnswersPanel.add(submitAnswers);
//Add submitAnswersPanel to test content panel
testContentPanel.add(submitAnswersPanel);
//Create scroll pane to allow for scrollable test (contents cannot fit one page)
JScrollPane testScrollPane = new JScrollPane();
testScrollPane.setViewportView(testContentPanel);
//Get rid of horizontal scroll bar and add vertical scrollbar
testScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
testScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Speed up scrolling
testScrollPane.getVerticalScrollBar().setUnitIncrement(16);
testFrame.add(testScrollPane);
//Experiment to show button
testFrame.setVisible(true);
}
I've refactored your code a little to use method to create the individual components of the GUI. You can find the full code at this ideone link
What I saw when I first copied your code to my machine was that the only thing visible was the button. So I create all the components in their own methods and then added them to the frame and panels using the Border Layout. This then enabled me to put the instructions in the NORTH sections, the button in the SOUTH section and then the main bits would go in the CENTER section.
One thing to note about the sections: (From the documentation)
The components are laid out according to their preferred sizes and the constraints of the container's size. The NORTH and SOUTH components may be stretched horizontally; the EAST and WEST components may be stretched vertically; the CENTER component may stretch both horizontally and vertically to fill any space left over.
So you should add the component you want to scale in size to the CENTER section.
My main method now looks like this:
public static void main(final String[] args) {
final JButton submitAnswers = createSubmitAnswersButton();
final JPanel instructionsPanel = createInstructionsPanel();
final JPanel testContentPanel = createContentPanel();
testContentPanel.add(instructionsPanel, BorderLayout.NORTH);
testContentPanel.add(submitAnswers, BorderLayout.SOUTH);
final JScrollPane scrollingContentPane = createScrollPaneFor(testContentPanel);
final JFrame testFrame = createJFrame();
testFrame.add(scrollingContentPane, BorderLayout.CENTER);
testFrame.setVisible(true);
}
Alright so I've got this JFrame with a screen on it. I've set the size to 800 by 800. However the window is created smaller than that. It's not a problem with the taskbar because it's not fullsize.
package sharph;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Main extends JFrame {
public static String Title = "Game 1";
public static Dimension screenSize = new Dimension(800,800);
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle(Title);
frame.setSize(screenSize);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
Screen screen = new Screen();
screen.setSize(screenSize);
frame.add(screen);
frame.setVisible(true);
}
}
In the screen class the paint method draws a box around where the border should be:
//Draw border
g.setColor(Color.RED);
g.drawRect(1, 1, 799, 799);
When I run it, the window is smaller than the box and the bottom and right sides are cut off.
Note the second picture I manually re-sized to show the border difference.
I realize that I have drawn the box 1 pixel smaller on each side, but the difference is much more than 2 pixels.
This happens because the content needs to squeezed into the size of the frame minus its borders.
Checkout this question and this question for a more detailed explanation
The layout manager is also overriding the size property you set on the Screen component. In either case, you should be overriding the getPreferredSize method of the Screen class
Also, you shouldn't be relying on magic numbers or assumptions about the actual size of the component, but should, instead, be using getWidth and getHeight instead (I know, it's just for demonstration purposes)
Instead of "screen.setSize(screenSize);" type "screen.setPreferredSize(screenSize);" and then after you type "frame.setVisible(true);" type "frame.pack()". You can also remove "frame.setSize(screenSize);" if you want to.
So I'd like to make a Canvas based Java application. I've extended my main class to Canvas and I size it in it's constructor.
public CanvasApp() {
Dimension size = new Dimension(640, 480);
setSize(size);
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
}
and in the main function, I make a frame for it, like this:
CanvasApp cnv = new CanvasApp();
JFrame frame = new JFrame("");
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(null); //I've tried this
panel.setSize(640,480); //but still doesn't work =(
panel.add(cnv, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
But the content pane appears 650x490 in size. Why is this?
I've attached a picture too.
I've drew a line from 0,0 to 640,480
Because a JFrame has a 5px border around it, look at any frame on your computer screen you'll notice a kind of embossed border - that border is 5 px in width adding 10 pixels onto height and width. You've only assigned the panel to 640 x 480 and plonked it inside the frame - the frame then adds it's own border onto that.
Thats probably because every JComponen have a border, you put your CanvasApp inside JPanel and JPanel itself into JFrame. That is probably the reason why you get bigger dimensions at the end.
See the oracle website on how to use borders here: http://docs.oracle.com/javase/tutorial/uiswing/components/border.html