Dynamically resize outer JPanel depending on JPanels inner JTextPane height - java

I have a JTextPane inside a JPanel, this JTextPane is at runtime being populated with text. I want the JPanel that is holding the JTextPane to dynamically change in height when JTextPane gets more than one line of text.
This is what ive got so far:
pnlChatMsgs = new JPanel(new BorderLayout());
pnlChatMsgs.setBackground(new java.awt.Color(244, 244, 244));
pnlMainTable.add(pnlChatMsgs, c);
pnlMidLiveType = new JPanel(new BorderLayout());
pnlMidLiveType.setPreferredSize(new Dimension(100, 30));
JTextPane.setFont(new java.awt.Font("Lucida Grande", 0, 13));
JTextPane.setText("<html></html>");
JTextPane.setContentType("text/html");
JTextPane.setForeground(new java.awt.Color(153, 153, 153));
JTextPane.setBackground(new java.awt.Color(250, 250, 250));
pnlMidLiveType.add(JTextPane, BorderLayout.NORTH);
pnlChatMsgs.add(pnlMidLiveType, BorderLayout.SOUTH);
pnlMidLiveType.setVisible(false);
So when JTextPane grows in size i want to change the height of the pnlMidLiveType JPanel.
How could i accomplish this?

Consider the following example. It demonstrates expandable JFrame and JPanel:
final JFrame frame = new JFrame();
JPanel panel = new JPanel(new BorderLayout());
JTextPane pane = new JTextPane();
pane.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
frame.pack();
}
});
panel.add(pane, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
JFrame#pack() triggers resize event and does the trick.

Related

Java Swing Scrollpane not scrolling

I want to be able to scroll down a dynamically generated list of movies. I tried adding a Scrollpane.
I have a navigation bar at the page start and in the center a jpanel with all the movies.
You can recreate this example by using this code:
private static JFrame frame;
public static void main(String[] args) throws HeadlessException {
frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setBackground(new Color(32, 32, 32));
JPanel navigationPanel = createNavigationBar();
frame.add(navigationPanel, BorderLayout.PAGE_START);
JPanel moviePanel = createMoviePanel();
frame.add(moviePanel, BorderLayout.CENTER);
frame.setPreferredSize(new Dimension(1920, 1080));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Example App");
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
// MoviePanel Class
public static JPanel createMoviePanel() {
JPanel parentMoviePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 25));
JPanel contentPanel = new JPanel(new GridLayout(0, 1));
JPanel moviePanel = new JPanel(new GridLayout(0, 9, 8, 5));
JScrollPane scrollPane = new JScrollPane(moviePanel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
parentMoviePanel.setBackground(new Color(32, 32, 32));
contentPanel.setBackground(new Color(32, 32, 32));
moviePanel.setBackground(new Color(32, 32, 32));
final File root = new File("");
for (int i = 0; i < 70; i++) {
// Get the image and scale it down
BufferedImage movieCover=new BufferedImage(150,200,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d=(Graphics2D)movieCover.getGraphics();
g2d.setColor(Color.GRAY);
g2d.fillRect(0,0,movieCover.getWidth(),movieCover.getHeight());
// Create button and change settings
JButton movieButton = new JButton("Movie " + i, new ImageIcon(movieCover));
movieButton.setMargin(new Insets(0, 0, 0, 0));
movieButton.setPreferredSize(new Dimension(180, 250));
movieButton.setForeground(Color.WHITE);
movieButton.setContentAreaFilled(false);
movieButton.setBorderPainted(false);
movieButton.setFocusPainted(false);
movieButton.setHorizontalTextPosition(JButton.CENTER);
movieButton.setVerticalTextPosition(JButton.BOTTOM);
moviePanel.add(movieButton);
scrollPane.revalidate();
}
contentPanel.add(moviePanel);
contentPanel.add(scrollPane);
parentMoviePanel.add(contentPanel);
return parentMoviePanel;
}
// Navbar Class
public static JPanel createNavigationBar() {
JPanel navBar = new JPanel();
navBar.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 20));
navBar.setBackground(new Color(25, 25, 25));
JButton homeButton = new JButton("Home");
homeButton.setContentAreaFilled(false);
homeButton.setBorderPainted(false);
homeButton.setFocusPainted(false);
JButton movieButton = new JButton("Movies");
movieButton.setContentAreaFilled(false);
movieButton.setBorderPainted(false);
movieButton.setFocusPainted(false);
// Add all the buttons to the navbar
navBar.add(homeButton);
navBar.add(movieButton);
return navBar;
}
What I'm trying to do is to scroll down this list of movies, using my mouse wheel without seeing any kind of scrollbar. It should look exactly how it looks now, but I want to be able to scroll down and see all the movies.
I don't know why it isn't working that's why I'm asking here in hope someone can explain to me what I'm doing wrong.
Your usage of a scroll pane is incorrect.
A Swing component can only have a single parent. The following code is creating the scroll pane with a child component. However you then remove the moviePanel from the scroll pane when you add it to the content pane.
So the scroll pane has no child component and will never work.
JScrollPane scrollPane = new JScrollPane(moviePanel);
...
contentPanel.add(moviePanel);
contentPanel.add(scrollPane);
However, even that won't solve your problem because you are now using a FlowLayout on your top level panel so all the child components will always be displayed at their preferred size so there is no need for scroll bars.
Get rid of all the scroll pane logic in your createMoviePanel() method.
Instead you probably want to add the scroll pane to the content pane:
//frame.add(moviePanel, BorderLayout.CENTER);
frame.add(new JScrollPane(moviePanel), BorderLayout.CENTER);
Now the scroll pane will dynamically resize as the frame size changes. Scrollbars will then appear as required.

How to align JLabels and JPanels to the left inside BoxLayout?

I want to align Labels and a Panel (containing Buttons) to the left inside a vertical BoxLayout.
As long as I don't add the panel to the BoxLayout everything is aligned to the left perfectly, but adding it screws everything up.
import javax.swing.*;
import java.awt.*;
public class BoxLayoutDemo{
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel five = new JPanel();
JButton plus = new JButton("+");
JButton minus = new JButton("-");
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
Font testFont = new Font("Arial", Font.BOLD, 20);
JLabel label1 = new JLabel("Label1");
label1.setFont(testFont);
JLabel label2 = new JLabel("Label2");
label2.setFont(testFont);
five.setLayout(new BoxLayout(five, BoxLayout.X_AXIS));
plus.setMinimumSize(new Dimension(30, 30));
plus.setMaximumSize(new Dimension(30, 30));
minus.setMinimumSize(new Dimension(30, 30));
minus.setMaximumSize(new Dimension(30, 30));
five.add(plus);
five.add(minus);
panel.add(label1);
panel.add(five);
panel.add(label2);
panel.setOpaque(true);
panel.setBackground(Color.red);
frame.setMinimumSize(new Dimension(200, 200));
frame.getContentPane().add(panel, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Your components need to have the same "x alignment":
label1.setAlignmentX(Component.LEFT_ALIGNMENT);
label2.setAlignmentX(Component.LEFT_ALIGNMENT);
five.setAlignmentX(Component.LEFT_ALIGNMENT);
Read the section from the Swing tutorial on Fixing Alignment Problems for more information.
You can use invisible components as fillers.
private static Box leftAlignedInHorizontalBox(Component component) {
Box box = Box.createHorizontalBox();
box.add(component);
box.add(Box.createHorizontalGlue());
return box;
}
and then:
panel.add(leftAlignedInHorizontalBox(label1));

Trying to add ScrollPane in Jpanel with null layout inside BorderLayout

I am trying to add a scrollbar in jpanel with null layout.
I want to create a form. This should should display few buttons at the bottom at all times.Any content inside form should maintain it's size and ratio even if the parent container is resized.
Here is what I've come with. I have a panel with borderlayout and added buttons at the south of border. Then created another jpanel to contain form that is added at the center of parent jpanel. Since I want form to maintain it's ratio I went with null layout for inner panel. But I want it to display scrollbar when content is not fully visible. enter image description here
Now adding inner jpanel into scrollpane and adding scrollpanel into parent panel (.add(scrollpane, BorderLayout.CENTER)) doesn't give desired format.
Is there any thing that I can do to get desired format?
Here is code Sample:
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(new Dimension(1000, 700));
Container c = jFrame.getContentPane();
c.setLayout(new BorderLayout());
bottomPanel(c);
centerPanel(c); //scrollbar should go in this panel
jFrame.setVisible(true);
}
private static void centerPanel(Container c) {
JPanel centerPanel = new JPanel();
centerPanel.setLayout(null);
JButton button = new JButton("This jObject should not resize when window resizes and also should maintain relative position.");
button.setBounds(new Rectangle(10, 10, 600, 50));
JButton button1 = new JButton("Just like it works in this code. Just Add ScrollPane to centerPanel That is in green backround");
button1.setBounds(new Rectangle(10, 70, 600, 50));
JButton button2 = new JButton("For clearity");
button2.setBounds(new Rectangle(10, 130, 600, 50));
centerPanel.add(button);
centerPanel.add(button1);
centerPanel.add(button2);
centerPanel.setBackground(Color.GREEN);
c.add(centerPanel, BorderLayout.CENTER);
}
private static void bottomPanel(Container c) {
JPanel bottomPanel = new JPanel(); //Buttons that goes at the bottom of screen will go in here
JPanel bottomInnerPanel = new JPanel();
bottomInnerPanel.setLayout(new BorderLayout());
bottomPanel.setLayout(new GridLayout());
bottomInnerPanel.add(new JButton("Add"), BorderLayout.WEST);
bottomInnerPanel.add(new JButton("Search"), BorderLayout.EAST);
bottomPanel.add(bottomInnerPanel);
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
c.add(bottomPanel, BorderLayout.SOUTH);
}

How to resize a JTextField within a JFrame?

I am just creating a simple GUI for practice I want to have a few text boxes within my JFrame but I the JTextField I created is taking up the whole frame. I tried doing .setSize but that didn't work.
JFrame
public static Component textbox(String x){
JLabel lbltAm= new JLabel(x);
JTextField tftAm = new JTextField(20);
lbltAm.setLabelFor(tftAm);
lbltAm.setFont(new Font("Serif", Font.PLAIN, 18));
tftAm.setSize(10, 10);
return tftAm;
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Tip Calculator");
//Add Textbox
frame.add(textbox("TipAmmount"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.gray);
frame.setPreferredSize(new Dimension(250, 400));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
It's because you are not using any layout I suggest to use FlowLayout and GridBagLayout.
Instead of returning JTextField return a Panel object and add the JTextField and Jlabel Object into the panel.You can use any layout I've used BorderLayout
public static Component textbox(String x){
JPanel panel = new JPanel(new BorderLayout());
JLabel lbltAm= new JLabel(x);
JTextField tftAm = new JTextField(20);
lbltAm.setLabelFor(tftAm);
lbltAm.setFont(new Font("Serif", Font.PLAIN, 18));
tftAm.setSize(10, 10);
panel.add(lbltAm, BorderLayout.NORTH);
panel.add(tftAm, BorderLayout.CENTER);
return panel;
}
There are multiple layout using which you can layout components in a Panel. have a look
Its not a good practice to add components directly to JFrame
use it like this
frame.getContentPane().add(component)
or if using borderlayout you can add like this
frame.getContentPane().add(compnent, BorderLayout.CENTER);

Resizing JFrame while shrinking a scrollpane acordingly

I currently have a JFrame to start fullscreen, inside this jframe i have a jpanel, this jpanel includes a vertical scrollpane. Now if i resize my jframe vertically it just kinda removes the bottom part of the jpanel. Is there any way to just shrink the jscrollpane.
im currently using flowlayout for the jframe,
Scrollbar appear automatically when the preferred size of the components added to the scroll pane area greater than the size of the scroll pane.
The FlowLayout will wrap components to a new row, but it always gives the preferred size as the size required to fit the components on a single row, so the preferred height will never change.
To solve this problem you can use the Wrap Layout which simple extend FlowLayout to recalculate the preferred size when wrapping occurs.
The JPanel consists of 3 other panels, a top panel, a scrollpane in the middle and a botpanel. The top and bot panel are just button and checkboxes and stuff
private void initPane() {
createFolderCompPanel();
createBotPanel();
createTopPanel();
createScrollPane();
createTotalPanel();
add(totalPanel);
}
private void createFolderCompPanel() {
//Create folderCompPanel
folderCompPanel = new JPanel();
folderCompPanel.setLayout(new BoxLayout(folderCompPanel, BoxLayout.Y_AXIS));
folderCompPanel.add(Box.createVerticalGlue());
}
private void createTotalPanel() {
//Create TotalPanel
totalPanel = new JPanel();
totalPanel.setLayout(new BoxLayout(totalPanel, BoxLayout.Y_AXIS));
totalPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
totalPanel.add(topPanel);
totalPanel.add(scrollPane);
totalPanel.add(botPanel);
}
private void createScrollPane() {
//Create ScrollPane
scrollPane = new JScrollPane();
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setViewportBorder(BorderFactory.createEtchedBorder());
scrollPane.getVerticalScrollBar().setUnitIncrement(6);
}
private void createBotPanel() {
//Create BotPanel
botPanel = new JPanel();
botPanel.setLayout(new BoxLayout(botPanel, BoxLayout.X_AXIS));
//AddButton
addButton = new JButton("Add");
addButton.setEnabled(false);
addButton.addActionListener(this);
//SaveButton
saveButton = new JButton("Save");
saveButton.setEnabled(false);
saveButton.addActionListener(this);
//CancelButton
cancelButton = new JButton("Cancel");
cancelButton.setEnabled(false);
cancelButton.addActionListener(this);
lblTotalLength = new JLabel("Total Length: " + totalLength);
botPanel.add(Box.createRigidArea(new Dimension(10, 0)));
botPanel.add(addButton);
botPanel.add(Box.createRigidArea(new Dimension(10, 0)));
botPanel.add(lblTotalLength);
botPanel.add(Box.createHorizontalGlue());
botPanel.add(saveButton);
botPanel.add(Box.createRigidArea(new Dimension(10, 0)));
botPanel.add(cancelButton);
botPanel.add(Box.createRigidArea(new Dimension(10, 0)));
}
private void createTopPanel() {
//Create TopPanel
topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
//create deletedisplay button
deleteDisplayButton = new JButton("Delete Display");
deleteDisplayButton.addActionListener(this);
deleteDisplayButton.setEnabled(false);
//create displaybox
displayBox = new JComboBox();
displayBox.addActionListener(this);
displayBox.addItem("<None>");
for (String s : connect.getAllDisplays()) {
displayBox.addItem(s);
}
displayBox.setMaximumSize(displayBox.getPreferredSize());
//create newdisplay button
newDisplayButton = new JButton("New Display");
newDisplayButton.addActionListener(this);
topPanel.add(Box.createRigidArea(new Dimension(10, 0)));
topPanel.add(displayBox);
topPanel.add(Box.createHorizontalGlue());
topPanel.add(newDisplayButton);
topPanel.add(Box.createRigidArea(new Dimension(5, 0)));
topPanel.add(deleteDisplayButton);
topPanel.add(Box.createRigidArea(new Dimension(10, 0)));
}
this is the panel i add to the jframe
public GuiConstructor(){
super(APPLICATION_NAME);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setMinimumSize(new Dimension(630, 600));
setLayout(new FlowLayout(FlowLayout.LEFT));
LoopControlWindow folderSearch = new LoopControlWindow(connect, this);
add(folderSearch);
pack();
setLocationRelativeTo(null);
setResizable(true);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Categories