I'm currently working on a media player for java, and with the power of VLCJ I was working on implementing an equalizer adjust window. There will be 11 vertical sliders with a JLabel underneath them indicating the hZ band and the dB level of the band. However, the slider keeps adding a huge gap between itself and the JLabel. I tried stacking just two JLabels on top of each other and there's barely a gap at all. My code is below. (The return equalizer stuff hasn't been implemented yet. I just want a basic UI working before I start adding in the functionality)
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import uk.co.caprica.vlcj.player.Equalizer;
public class VideoEQFrame {
public VideoEQFrame() {
//constructor
}
public Equalizer show() {
JFrame frame = new JFrame("Effects");
JPanel panel = new JPanel();
JPanel sliders= new JPanel();
JPanel gainObjects = new JPanel(new GridLayout(2, 0, 2, 0));
JSlider gainS = new JSlider(JSlider.VERTICAL, -12, 12, 0);
gainS.setMajorTickSpacing(2);
gainS.setPaintTicks(true);
gainS.setToolTipText("Adjust the gain");
JLabel gainL = new JLabel("Text");
gainObjects.add(gainS);
gainObjects.add(gainL);
sliders.add(gainObjects);
panel.add(sliders);
frame.add(panel);
frame.setSize(new Dimension(600, 300));
//frame.setResizable(false);
frame.setVisible(true);
Equalizer eq = new Equalizer(0);
return eq;
}
}
You are using GridLayout to lay the slider and the text label. That means that they will both occupy the same height. So because the slider has bigger height, the height of the label also adjusts to this height. Try using another LayoutManager like BorderLayout, like so:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class VideoEQFrame {
public VideoEQFrame() {
//constructor
}
public void show() {
JFrame frame = new JFrame("Effects");
JPanel panel = new JPanel();
JPanel sliders= new JPanel();
JPanel gainObjects = new JPanel(new BorderLayout());
JSlider gainS = new JSlider(JSlider.VERTICAL, -12, 12, 0);
gainS.setMajorTickSpacing(2);
gainS.setPaintTicks(true);
gainS.setToolTipText("Adjust the gain");
JLabel gainL = new JLabel("Text");
gainObjects.add(gainS, BorderLayout.CENTER);
gainObjects.add(gainL, BorderLayout.PAGE_END);
sliders.add(gainObjects);
panel.add(sliders);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
//frame.setResizable(false);
frame.setVisible(true);
// Equalizer eq = new Equalizer(0);
// return eq;
}
public static void main(final String[] args) {
new VideoEQFrame().show();
}
}
Related
So for a school project I made a grade book in java. When creating the gui I used hardcoded values in the setBounds() methods. Now this worked when I had a 1024×768 screen resolution it looked alright, but when I got a new laptop and it had a 4k screen it looked super small when I ran the program.
So my question would be is there a way to dynamically change the size of the Jframe and all of the associated objects on the frame so it matches the resolution of the screen?
I know that you can get the screen resolution from this
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
but I do not know what would be the best way to do this.
Taking your approach as example and taking this answer and this tutorial as base, here you have the clues:
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
public class Q1 extends JFrame {
public static void main(String[] args) {
Q1 frame = new Q1();
frame.setSize(300, 300);
frame.setMinimumSize(new Dimension(300, 300));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public Q1() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
#Override
public void validate() {
resize();
super.validate();
};
private void resize() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width + "," + height);
}
}
This will print the size of the screen when your resize the frame, so you just need to add an if/else in the resize method to make frame bigger
OUTPUT
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
A layout manager is an object that implements the LayoutManager
interface* and determines the size and position of the components
within a container. Although components can provide size and alignment
hints, a container's layout manager has the final say on the size and
position of the components within the container.
See the example I found using layout managers.Hope you get some idea.THe original author is here Set a layout manager like BorderLayout and then define more specifically, where your panel should go: like
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.add(mainPanel, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
puts the panel into the center area of the frame and lets it grow automatically when resizing the frame.See below example for full usage:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestLayoutManagers {
private JPanel northFlowLayoutPanel;
private JPanel southBorderLayoutPanel;
private JPanel centerGridBagLayoutPanel;
private JPanel westBoxLayoutPanel;
private JPanel eastGridLayoutPanel;
private final JButton northButton = new JButton("North Button");
private final JButton southButton = new JButton("South Button");
private final JButton centerButton = new JButton("Center Button");
private final JButton eastButton = new JButton("East Button");
private final JButton westButton = new JButton("West Button");
public TestLayoutManagers() {
northFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
southBorderLayoutPanel = new JPanel(new BorderLayout());
centerGridBagLayoutPanel = new JPanel(new GridBagLayout());
eastGridLayoutPanel = new JPanel(new GridLayout(1, 1));
Box box = Box.createHorizontalBox();
westBoxLayoutPanel = new JPanel();
northFlowLayoutPanel.add(northButton);
northFlowLayoutPanel.setBorder(BorderFactory.createTitledBorder("Flow Layout"));
southBorderLayoutPanel.add(southButton);
southBorderLayoutPanel.setBorder(BorderFactory.createTitledBorder("Border Layout"));
centerGridBagLayoutPanel.add(centerButton);
centerGridBagLayoutPanel.setBorder(BorderFactory.createTitledBorder("GridBag Layout"));
eastGridLayoutPanel.add(eastButton);
eastGridLayoutPanel.setBorder(BorderFactory.createTitledBorder("Grid Layout"));
box.add(westButton);
westBoxLayoutPanel.add(box);
westBoxLayoutPanel.setBorder(BorderFactory.createTitledBorder("Box Layout"));
JFrame frame = new JFrame("Test Layout Managers");
frame.setLayout(new BorderLayout()); // This is the deafault layout
frame.add(northFlowLayoutPanel, BorderLayout.PAGE_START);
frame.add(southBorderLayoutPanel, BorderLayout.PAGE_END);
frame.add(centerGridBagLayoutPanel, BorderLayout.CENTER);
frame.add(eastGridLayoutPanel, BorderLayout.LINE_END);
frame.add(westBoxLayoutPanel, BorderLayout.LINE_START);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestLayoutManagers testLayoutManagers
= new TestLayoutManagers();
}
});
}
}
I am creating a GUI with a graphics panel, a command panel and a Command List panel. I've got the command panel where I want it at the bottom of the frame using BorderLayout South but my side panel is just tiny and unreadable.
Ill provide a picture of what I want my frame to look like at the end:
What I currently have:
Could anyone explain why the TitledBorder panel is so small?
My code is below:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class PenDriver {
public static void main(String[] args) {
JFrame frame = new JFrame("Pen Simulator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
penPanel panel = new penPanel();
frame.add(panel);
frame.setVisible(true);
}
}
AND
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
public class penPanel extends JPanel {
private JTextField userCommand;
private JLabel instruction1;
private JButton instruct, clear;
private JLabel cmd1;
public penPanel() {
setLayout(new BorderLayout());
// CREATE THE COMMAND PANEL///////
// Set Layout
JPanel command = new JPanel();
command.setLayout(new BoxLayout(command, BoxLayout.LINE_AXIS));
// Create Label and add to panel
instruction1 = new JLabel("Enter Command:");
// Create Buttons
instruct = new JButton("Execute");
clear = new JButton("Clear Graphics");
// Create Text Field to panel
userCommand = new JTextField(10);
command.add(instruction1);
command.add(Box.createRigidArea(new Dimension(4, 0)));
command.add(userCommand);
command.add(Box.createRigidArea(new Dimension(2, 0)));
command.add(instruct);
command.add(Box.createRigidArea(new Dimension(2, 0)));
command.add(clear);
// COMMAND PANEL FINISHED////////
// CREATE THE COMMAND LIST PANEL//////////
JPanel cmdList = new JPanel();
cmdList.setBorder(BorderFactory.createTitledBorder("Command List:"));
cmdList.setLayout(new BoxLayout(cmdList, BoxLayout.PAGE_AXIS));
cmd1 = new JLabel("UP = up");
cmdList.setSize(new Dimension(50, 400));
cmdList.add(cmd1);
add(command, BorderLayout.SOUTH);
add(cmdList, BorderLayout.EAST);
}
}
Thank you!
EDIT: After some tinkering to this code:
cmdList.setPreferredSize(new Dimension(120, 800));
cmdList.add(cmd1);
add(command, BorderLayout.SOUTH);
command.add(Box.createRigidArea(new Dimension(120, 0)));
add(cmdList, BorderLayout.EAST);
Still not quite what im going for and not sure if it's what I am supposed to do. Should I be altering the driver file rather than the JPanels directly?
Notice how there is still a gap to the right of the "Clear Graphics" Button. Any way to get rid of that?
Could anyone explain why the TitledBorder panel is so small?
The size of the text in the border is not used to determine the size of the component. So the width is determined by the preferred size of the component you add to the panel.
So you need to override the getPreferredSize() method of the panel to return the maximum of the default preferred size calculation or the size of the titled border:
JPanel cmdList = new JPanel()
{
#Override
public Dimension getPreferredSize()
{
Dimension preferredSize = super.getPreferredSize();
Border border = getBorder();
int borderWidth = 0;
if (border instanceof TitledBorder)
{
Insets insets = getInsets();
TitledBorder titledBorder = (TitledBorder)border;
borderWidth = titledBorder.getMinimumSize(this).width + insets.left + insets.right;
}
int preferredWidth = Math.max(preferredSize.width, borderWidth);
return new Dimension(preferredWidth, preferredSize.height);
}
};
Notice how there is still a gap to the right of the "Clear Graphics" Button. Any way to get rid of that?
command.add(Box.createRigidArea(new Dimension(120, 0)));
You just added the rigid area to the command panel so you asked to have the extra 120 pixels at the end.
JPanel panel = new JPanel(new GridLayout(0,1));
JScrollPane contentpane = new JScrollPane(panel);
JButton add = new JButton("ADD");
add.actionListener(new ActionListener() {
public void actionPerformed(){
MyPanel newpanel = new MyPanel("title","Button"); //MyPanel is a class which extends JPanel and contains constructor MyPanel(String TitleToSet ,String ButtonTitleTOAdd)
panel.add(newpanel);
panel.repaint();
}) ;
I have used this code thinking that it will add the MyPanel to the grid layout dynamically and "panel" would be scrollable if more "MyPanel"s are added. However, this was not the case, 1st "MyPanel" filled whole "panel" and on adding second "MyPanel" (by clicking button "Add"), the 1st "MyPanel" was shrinked to make space for second one to be added.. and on adding more, all the "MyPanel"s were fit in the viewport instead of making the "panel" scrollable.. How to add those "MyPanel"s dynamically and making the "panel" scrollable on adding more of those?? Any help would be appreciated.
http://docs.oracle.com/javase/7/docs/api/javax/swing/JScrollPane.html :
By default JScrollPane uses ScrollPaneLayout to handle the layout of
its child Components. ScrollPaneLayout determines the size to make the
viewport view in one of two ways:
[...]
getPreferredSize is used.
You should add the line
panel.setPreferredSize(new Dimension(0, panel.getComponents().size() * SUB_PANEL_HEIGHT));
to your ActionListener.
Full example:
package main;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Timer;
class Test {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(400, 400));
frame.setSize(400, 400);
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(new JLabel("BOO"));
panel.add(new JButton("BBBB"));
JScrollPane contentpane = new JScrollPane(panel);
frame.add(contentpane);
new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel newpanel = new JPanel();
newpanel.add(new JLabel("LOL"));
panel.add(newpanel);
System.out.println(100 * panel.getComponents().length);
panel.setPreferredSize(new Dimension(0, 100 * panel.getComponents().length));
contentpane.validate();
}
}).start();
frame.setVisible(true);
}
}
I am creating a bespoke table that I want to scroll up and down, so I am using JScrollPane.
My problem is that each time I add another row in the table it is adding it to the side of the last one, rather than below the last line, which is where I want it to be. Eg it is adding columns to the table rather than rows.
The number of rows that need to be added is uncertain and depends on how many entries there are in the table.
I know I can use a table but for the purposes of this exercise I want to do it this way.
Below is an MCVE version of my code that demonstrates the problem. I left the colour change in so the fields are more visible:
public class Customers {
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200,500);
frame.setVisible(true);
}
public static void ScrollCustomersGui(){
JPanel Table = new JPanel();
Table.add(customersTableHeadings(Table));
Table.add(customersTableHeadings(Table));
Table.add(customersTableHeadings(Table));
JScrollPane scroll = new JScrollPane(Table);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings(JPanel panel){
FlowLayout FlowCustTable = (FlowLayout)panel.getLayout();
FlowCustTable.setHgap(0);
JPanel customersTable = new JPanel(FlowCustTable);
JTextField custid = new JTextField("ONE");
custid.setPreferredSize(new Dimension(500, 50));
custid.setBackground(Color.CYAN);
customersTable.add(custid);
return customersTable;
}
}
Use vertical BoxLayout here is the modified code :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Customers
{
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200, 500);
frame.setVisible(true);
}
public static void ScrollCustomersGui()
{
Box box = Box.createVerticalBox();
//JPanel Table = new JPanel();
//Table.setLayout(new BoxLayout(Table, BoxLayout.Y_AXIS));
box.add(customersTableHeadings());
box.add(customersTableHeadings());
box.add(customersTableHeadings());
JScrollPane scroll = new JScrollPane(box);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings()
{
// FlowLayout FlowCustTable = (FlowLayout) panel.getLayout();
// FlowCustTable.setHgap(0);
JPanel customersTable = new JPanel();
customersTable.setMaximumSize(new Dimension(550, 60));
JTextField custid = new JTextField("ONE");
custid.setPreferredSize(new Dimension(500, 50));
custid.setBackground(Color.CYAN);
customersTable.add(custid);
return customersTable;
}
public static void main(String[] args)
{
ScrollCustomersGui();
}
}
you are using a FlowLayout which will not work for your case you can use a BoxLayout check it here, you can also use a GridBagLayout but it is complex :)
I have a question about resizing a JPanel.
I have a JSlider, which resize a JPanel dynamycly. When i change the value Height() of JPanel, size of panel decreases or increases, from top to down, effect as the curtain, but when I change a value Width(), it does not effect curtain, Panel resizes from Center, and decreases or increases in both sides at the same time.
Dear experts, tell please how can I resize a Panel width from left to right, or backward?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JToolBar;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Swipe extends JFrame {
static JPanel panel = null;
static JPanel panel2 = null;
static JPanel panel3 = null;
static JLabel label1 = null;
static JLabel label2 = null;
static JSlider slider = null;
static JToolBar bar = null;
ImageIcon img;
public Swipe(ImageIcon img1, ImageIcon img2) {
JFrame frame = new JFrame();
bar = new JToolBar();
bar.add(slider(img1));
frame.add(bar, BorderLayout.NORTH);
label1 = new JLabel();
label1.setLayout(null);
label1.setMaximumSize(new Dimension(img2.getIconWidth(), img2.getIconHeight()));
label1.setIcon(img1);
panel = new JPanel();
panel.add(label1, new GridBagConstraints());
label2 = new JLabel();
label2.setPreferredSize(new Dimension(img2.getIconWidth(), img2.getIconHeight() + 20));
label2.setMaximumSize(new Dimension(img2.getIconWidth(), img2.getIconHeight()));
label2.setIcon(img2);
frame.setLayout(new FlowLayout());
label2.setLayout(new FlowLayout());
label2.add(panel);
frame.add(label2);
frame.setSize(img2.getIconWidth() + 50, img2.getIconHeight() + 50);
frame.setVisible(true);
frame.pack();
}
public JSlider slider(final ImageIcon im) {
slider = new JSlider();
slider.setMaximum(im.getIconHeight());
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
int value = slider.getValue();
//panel.setPreferredSize(new Dimension(im.getIconWidth(),value));
panel.setPreferredSize(new Dimension(value, im.getIconHeight()));
panel.repaint();
panel.updateUI();
}
});
return slider;
}
}
While it is surely possible to do your way, it is much simpler and easier to use JSplitPane to achieve I think the comparable goal:
new JSplitPane(JSplitPane.VERTICAL_SPLIT,
componentOnLeft, Component componentOnRight);
JSplitPane also has the setDividerLocation methods (one absolute, one proportional) if you need to resize the two components programmatically.