Java JPanel & JScrollPane - java

I working on a application that manage image's filters etc.
I want to have scroll bars when the image is to big to be display.
I put my customize panel that extend JPanel in a JScrollPane and I add it in my JFrame.
My image is displayed but not the whole image and the scroll bars are not there.
How to get the scroll-bars to appear?
Here is my code :
CustomePanel test = new ImagePanel(new File("test.jpg"));
test.setPreferredSize(new Dimension(400, 400));
JScrollPane tmp = new JScrollPane(test);
this.getContentPane().add(tmp);

It is likely that your initial preferred size does not match that of your Image. Rather than using setPreferredSize, override getPreferredSize to reflect the size of the image in ImagePanel:
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
A JLabel would be a better approach here if the panel is not required as a container.

try to set the same preferred size to scroll pane as well and test it

Related

Swing JScrollPane resizing to fit the viewport panel

I tried a lot of layout managers but none could solve my problem:
I want the items in a scrollPane to keep their size (preferred or minimum) and not being resized (reduced) to fit the viewport Panel. Since if it is a JTextArea, and if the text area has blank space and it is bigger then the viewport, it would reduce it so the blank text area won't be shown. I want the blank text area to be shown for appearance issues.
Im stacking one item after another using BoxLayout, and it seems to me that for text areas the setMinimum method fails.
If the text area has blank space, then the scrollbar of the ScrollPane won't appear, instead it only appears it there are no blank space left.
Any solution?
JScrollPane materialPane = new FScrollPane();
this.materialPaneView = new TPanel();
this.materialPaneView.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/2)));
this.materialPaneView.setLayout(new BoxLayout(this.materialPaneView, BoxLayout.Y_AXIS));
materialPane.setViewportView(materialPaneView);
materialPane.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/2)));
for(Material mat: this.unit.getMaterial()){
this.addMaterial(mat);
}
centerPanel.add(sectionPane);
centerPanel.add(exercisePane);
centerPanel.add(materialPane);
this.add(upperPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
public void addMaterial(Material mat){
JTextField matName = new JTextField(30);
JPanel fieldButtonPanel = new TPanel();
fieldButtonPanel.setLayout(new GridLayout(1,2));
JPanel fieldPanel = new TPanel(new FlowLayout(FlowLayout.LEFT));
JPanel deleteMatButtonPanel = new TPanel(new FlowLayout(FlowLayout.RIGHT));
matName.setText(mat.getName());
matName.setMaximumSize(new Dimension(FFont.def.getSize()*20, 30));
fieldPanel.add(matName);
JButton deleteMat = new JButton("Delete Material");
deleteMatButtonPanel.add(deleteMat);
fieldButtonPanel.add(fieldPanel);
fieldButtonPanel.add(deleteMatButtonPanel);
fieldButtonPanel.setAlignmentX(LEFT_ALIGNMENT);
JTextArea matText = new FTextArea(mat.getDesc(), (int)(WIDTH*0.95), (int)(HEIGHT/3.4));
matText.setMinimumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/3.5)));
/*matText.setMaximumSize(new Dimension((int)(WIDTH*0.95), (int)(HEIGHT/3.4)));*/
matText.setText(mat.getDesc());
matText.setAlignmentX(LEFT_ALIGNMENT);
this.materialPaneView.add(fieldButtonPanel);
this.materialPaneView.add(matText);
matName.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
mat.setName(matName.getText());
}
});
HEIGHT and WIDTH are constants, and TPanel FScrollPane are my predefined transparent panels. The BoxLayout panel is the viewport of a scrollPane, and still, it would resize the text areas.
I am not sure i get what you are asking for so please tell me if i totally missed the point...
As far as i know the Viewport size is controlled by the component inside the JScrollPane and the JScrollPane size wont change no matter what happens to the viewport.
You either want to:
A) Resize the JScrollPane to the same size as it's content.
I would implement listeners to look for the content size change and resize the ScrollPane accordingly but you need to pay attention to resize the whole Hierarchy too.
B) You want to resize the viewport so that it fits in the JScrollPane? Y'know without scrollbars.
I had this problem and fixed it by using a ScrollablePanel component. Check this answer, follow the link to download the .class and use it to use a JPanel that resizes to fit the ScrollPane.
Those arent very detailed answers but i will need more information about what you are trying to do before expanding on it. And your code isnt complete, always share a code that we can CTRL+C/V and readily verify the problem in our end.

How do you set the bounds of a JLabel in a JFrame?

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.

How can you add several elements to a JScrollPane

So I am trying to add more than one element to a JScrollPane element but so far I haven't been able to pull it of.
I can make it so that the first element shows up ,which in my case is a picture. But after adding in an extra panel to the JScrollPane ,the first element disappears and even the second element ,the new panel , doesnt show on my JScrollPane.
JFrame scherm = new JFrame("t?");
scherm.setVisible(true);
scherm.setSize(300, 300);
scherm.setLocationRelativeTo(null);
scherm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//
String path = "C:\\Users\\Bernard\\Documents\\Paradox Interactive\\Crusader Kings II\\mod\\viking\\map\\provinces.bmp";
Image image = ImageIO.read(new File(path));
ImageIcon icon = new ImageIcon(image);
JLabel label = new JLabel(icon);
JScrollPane scroll = new JScrollPane(label);
JPanel paneel2= new JPanel();
paneel2.setSize(new Dimension(400,400));
scroll.getViewport().add(paneel2,null);
scherm.add(scroll);
Thank you for your time!
By doing this:
scroll.getViewport().add(paneel2,null);
You're trying to add a component to the scroll pane's JViewPort shown in the picture below:
This makes no sense. As stated in How to Use Scroll Panes trial:
A
JScrollPane
provides a scrollable view of a component.
This single component is the view port's view. So if you want to have more than a single component in your scroll pane you must to wrap all those components in a lightweight component such as JPanel and set this one as the scroll pane's view port view:
JPanel content = new JPanel();
content.add(label);
content.add(paneel2);
scroll.setViewportView(content);

Why does my JButton appear the full size of the JFrame?

I am a newbie, I have a question. I am trying to use Eclipse to write a Java windows application, in which I will have a main window, which will contain several things, like a dashboard sort of thing, and it will have buttons, for example to add a record to a database, and this button when pressed, will open a new relevant window on top.
I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?
Can you suggest me better ideas for a design than what I specified ?
Thank you
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.getContentPane().add(button);
jfrm.setVisible(true);
}
Add a layout to the JFrame first. For example FlowLayout:
jfrm.setLayout(new FlowLayout());
"I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?"
The reason the button stretches is because JFrame has a default BorderLayout that does not respect the preferred sizes of child components.
The solution is to set the Layout Manager to layout that does respect preferred sizes. The image blow from this example shows the most common Layout Managers and show visually which one respect the preferred size of child components.
Also, the BorderLayout is also the reason your JLabel does not show. By default, every component that is added to a BorderLayout without a position specified e.g. BorderLayout.SOUTH, will automatically be placed in the BorderLayout.CENTER position. Each position may only have one component. So when you add the JLabel it goes to the CENTER, but when you add the JButton, it also goes the CENTER, kicking out the JLabel.
If you've never encountered Layout Managers, this is probably all confusing to you. You should take the time to go over How to Layout Components Within a Container
You need to use some form of layoutmanager, you can use this information: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You must use Layout manager.
Use this code..
public static void main(String[] args)
{
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.add(button);
jfrm.setVisible(true);
jfrm.setLayout(new FlowLayout());
jfrm.pack();
you forgot to add pack(). so use this code to get Jlabel and JButtion side by side.
Thanks...

java use size of JPanel to size components

Is it possible to use the size of a JPanel to set the size of components inside the JPanel? When I try to use getHeight() or getWidth() on the JPanel it always returns 0. I know that it gets it's size once the JFrame is packed, but how would one go about using the dimensions of the JPanel and applying it to a component inside it? Something like this
JPanel panel = new JPanel();
JLabel label = new JLabel();
label.setWidth(panel.getWidth());
panel.add(label);
EDIT:
See sample code below. What should I do if I want my Jlabel to be as wide as my JPanel? Is it wrong to use boxlayout in this case?
public class Main extends JFrame{
public Main(){
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.setBorder(BorderFactory.createLineBorder(Color.blue));
JLabel label = new JLabel();
label.setBorder(BorderFactory.createLineBorder(Color.red));
label.setText("label1");
label.setMinimumSize(panel.getPreferredSize());
label.setPreferredSize(panel.getPreferredSize());
panel.add(label);
add(panel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setSize(500,500);
setVisible(true);
}
public static void main(String[] args)
{
new Main();
}
}
Is it possible to use the size of a JPanel to set the size of components inside the JPanel?
This is the job of the layout manager.
When I try to use getHeight() or getWidth() on the JPanel it always returns 0
When the layout manager is invoked the Container will have a valid size so the layout manager can do its job properly.
There is no reason for you to be playing with sizes. Leave it to the layout managers to do their jobs.
Update:
What should I do if I want my Jlabel to be as wide as my JPanel? Is it wrong to use boxlayout in this case?
The BoxLayout attempts to respect the minimum/maximum size of the component. In you case you should be able to do something like:
JLabel label new JLabel("some text");
label.setBorder(....);
Dimension d = label.getPreferredSize();
d.width = 32767;
label.setMaximumSize( d );
Or maybe a simpler approach is to start with a BorderLayout. You can add the label to the NORTH. Then create another panel and add it to the CENTER.
Of course you can, but be careful that the result depends on the layout manager of your JPanel and on the number of its child components.
Setting the width ignores resizing. LayoutManagers typically ask components for their preferred widths and heights, and expand / contract items to maintain a visually appealing position after the frame has been resized. So, your best option is to leverage the layout manager and report a "preferred width".
You can use setPreferredWidth(...); but, if your preferred width is to change over the run of the program (due to window size changes), you will need to listen to the panel in question and update your button's preferred width as the panel's preferred width changes (this assumes it changes, which might not be true).

Categories

Resources