I am trying to do have two button in JFrame, and I call the setBounds method of them for setting the positions and size of them and also I passed null to setLayout1 because I want to usesetBounds` method of component.
Now I want to do something with my code that whenever I resize the frame buttons decoration will change in a suitable form like below pictures:
I know it is possible to use create an object from JPanel class and add buttons to it and at the end add created panel object to frame, but I am not allowed to it right now because of some reason (specified by professor).
Is there any way or do you have any suggestion?
My code is like this:
public class Responsive
{
public static void main(String[] args)
{
JFrame jFrame = new JFrame("Responsive JFrame");
jFrame.setLayout(null);
jFrame.setBounds(0,0,400,300);
JButton jButton1 = new JButton("button 1");
JButton jButton2 = new JButton("button 2");
jButton1.setBounds(50,50,100,100);
jButton2.setBounds(150,50,100,100);
jFrame.add(jButton1);
jFrame.add(jButton2);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
}
A FlowLayout with no horizontal spacing, some vertical spacing and large borders could achieve that easily. A null layout manager is never the answer to a 'responsive' robust GUI.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class ResponsiveGUI {
private JComponent ui = null;
ResponsiveGUI() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 8));
ui.setBorder(new EmptyBorder(10,40,10,40));
for (int i=1; i<3; i++) {
ui.add(getBigButton(i));
}
}
public JComponent getUI() {
return ui;
}
private final JButton getBigButton(int number) {
JButton b = new JButton("Button " + number);
int pad = 20;
b.setMargin(new Insets(pad, pad, pad, pad));
return b;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
ResponsiveGUI o = new ResponsiveGUI();
JFrame f = new JFrame("Responsive GUI");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
You could try to use:
jFrame.addComponentListener(new ComponentListener() {
// this method invokes each time you resize the frame
public void componentResized(ComponentEvent e) {
// your calculations on buttons
}
});
Related
I am trying to make an A* Pathfinding Visualizer but right now I am stuck on creating the grid. What is the best way of creating a grid like what is seen below? For instance, should I just use a bunch of JButton components or is there some other way?
Put JButton components in a GridLayout, using removeAll() on the panel before setting a new grid layout to change the number of columns and/or rows. Lastly pack() the top level container (in this case a JFrame) to fit the number of rows and columns.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.EmptyBorder;
public class ChangableButtonGrid {
private JComponent ui = null;
JPanel gridArea = new JPanel();
public static final int SIZE = 600;
JToolBar tools = new JToolBar("Tools");
SpinnerNumberModel colModel = new SpinnerNumberModel(20, 5, 50, 1);
SpinnerNumberModel rowModel = new SpinnerNumberModel(5, 5, 50, 1);
ChangeListener changeListener = (ChangeEvent e) -> {
refresh();
};
public ChangableButtonGrid() {
initUI();
}
public final void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
ui.add(gridArea);
ui.add(tools,BorderLayout.PAGE_START);
tools.setLayout(new FlowLayout(FlowLayout.LEADING));
addModelToToolbar("Cols", colModel);
addModelToToolbar("Rows", rowModel);
ui.add(gridArea);
}
private void refresh() {
int cols = colModel.getNumber().intValue();
int rows = rowModel.getNumber().intValue();
gridArea.removeAll();
gridArea.setLayout(new GridLayout(rows, cols));
for (int rr=0; rr<rows; rr++) {
for (int cc=0; cc<cols; cc++) {
JButton b = new JButton(cc + "," + rr);
gridArea.add(b);
}
}
Container c = gridArea.getTopLevelAncestor();
JFrame f = (JFrame)c;
f.pack();
}
private void addModelToToolbar(String label, SpinnerNumberModel model) {
tools.add(new JLabel(label));
JSpinner spinner = new JSpinner(model);
spinner.addChangeListener(changeListener);
tools.add(spinner);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
ChangableButtonGrid o = new ChangableButtonGrid();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
o.refresh();
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
I have a grid with data and a JComboBox with a lot of users in it, of which one is selected. I would like to scroll to the selected item to the area where user can't see the rest of the data(the bottom of the grid) so that my JScrollPane will jump to this area automatically.
How can I do that?
I think this has something to do with scrollRectToVisible() method.
A JComboBox needs no JScrollPane.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class OneLineCombo {
private JComponent ui = null;
OneLineCombo() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,20,4,20));
String[] fontFamily = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
JComboBox fontCombo = new JComboBox(fontFamily);
fontCombo.setMaximumRowCount(1);
ui.add(fontCombo, BorderLayout.PAGE_START);
ui.add(new JLabel("Type some letters of the font name to select it"),
BorderLayout.PAGE_END);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
OneLineCombo o = new OneLineCombo();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I want the JPanel at the center of the frame to be replaced when the corresponding buttons present in the JPanel to the left of the frame are pressed.
I am using cardlayout for replacing the panels in the center.
here is the sample code that i used for changing panels on button click ,but it doesn't work. can anyone let me know whats wrong in the code.
Library extends JFrame
Public Library(){
Container container = getContentPane();
container.setLayout( new BorderLayout() );
setExtendedState(JFrame.MAXIMIZED_BOTH);
banner = new BannerPanel();
container.add(banner,BorderLayout.NORTH);
MenuButtons = new MenuButtonPanel();
container.add(MenuButtons,BorderLayout.WEST);
SelectedButtonPanel = new SelectedPanel(container);
setLocationRelativeTo(null);
setVisible( true );
init();
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
MenuButtonPanel extends JPanel and has multiple buttons in it. The inner class of it ButtonHandler implements hte actionListner for the buttons
//inner class
class ButtonEventHandler implements ActionListener {
public void actionPerformed( ActionEvent event ){
SelectedPanel selectObj = new SelectedPanel();
if("about".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("about");
}
else if("checkout".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("checkout");
}
else if("search".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("search");
}
The SelectedPanel should display the replaced Jpanel in the center of the frame
public SelectedPanel() {}
public SelectedPanel(Container framePane)
{
addSelectedPanel(framePane);
}
public void addSelectedPanel(Container framePane)
{
cardPanel = new JPanel();
//set layout of panel
cardPanel.setLayout(new CardLayout());
cardPanel.setBorder(null);
cardPanel.setForeground(new Color(0, 0, 0));
//this.selObj = selObj;
aboutPanel = new About();
checkoutPanel = new Checkout();
searchPanel = new Search();
cardPanel.add(aboutPanel,ABOUTBUTTON);
cardPanel.add(checkoutPanel,CHECKOUTBUTTON);
cardPanel.add(searchPanel, SEARCHBUTTON);
framePane.add(cardPanel, BorderLayout.CENTER); }
The selectedPanel class also has method showReplacePanel() which is called in the actionPerformed of the buttonClick.
public void showReplacePanel(String selObj)
{
System.out.println("cardlayout entered");
CardLayout cl = (CardLayout)(cardPanel.getLayout());
System.out.println("cardlayout entered");
switch(selObj){
case "about":
cl.show(cardPanel,ABOUTBUTTON);
break;
case "search":
//this.repPanel = searchPanel;
cl.show(cardPanel,SEARCHBUTTON);
break;
case "checkout":
cl.show(cardPanel,CHECKOUTBUTTON);
//this.repPanel = checkoutPanel;
break;
I created an example for you, take a look at the actionPerformed(ActionEvent e) method
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelSwap extends JPanel implements ActionListener {
JPanel firstPanel = new JPanel();
JPanel secondPanel = new JPanel();
public PanelSwap() {
super(new BorderLayout());
firstPanel.setBackground(Color.RED);
secondPanel.setBackground(Color.YELLOW);
JButton swap1 = new JButton("SwapToYellow");
swap1.addActionListener(this);
JButton swap2 = new JButton("SwapToRed");
swap2.addActionListener(this);
firstPanel.add(swap1);
secondPanel.add(swap2);
add(firstPanel);
}
/** Listens to the buttons and perfomr the swap. */
public void actionPerformed(ActionEvent e) {
for (Component component : getComponents())
if (firstPanel == component) {
remove(firstPanel);
add(secondPanel);
} else {
remove(secondPanel);
add(firstPanel);
}
repaint();
revalidate();
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("PanelSwap");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
JComponent newContentPane = new PanelSwap();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I'd like to custom a little bit the basic JSpinner of swing java API.
Basically, I want to move the textfield component initially located on the left of the arrow buttons. Instead, the texfield would be lcoated between the two arrows of the spinner, so that there's one arrow on top of the textfield and one arrow below the texfield.
But I don't know how to proceed...
Anyone would have an idea?
You might be able to override the setLayout(LayoutManager) method of JSpinner to use a custom LayoutManager.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SpinnerLayoutTest {
public JComponent makeUI() {
SpinnerNumberModel m = new SpinnerNumberModel(10, 0, 1000, 1);
JSpinner spinner = new JSpinner(m) {
#Override public void setLayout(LayoutManager mgr) {
super.setLayout(new SpinnerLayout());
}
};
JPanel p = new JPanel(new BorderLayout(5,5));
p.add(new JSpinner(m), BorderLayout.NORTH);
p.add(spinner, BorderLayout.SOUTH);
p.setBorder(BorderFactory.createEmptyBorder(16,16,16,16));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SpinnerLayoutTest().makeUI());
f.setSize(320, 160);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class SpinnerLayout extends BorderLayout {
#Override public void addLayoutComponent(Component comp, Object constraints) {
if("Editor".equals(constraints)) {
constraints = "Center";
} else if("Next".equals(constraints)) {
constraints = "North";
} else if("Previous".equals(constraints)) {
constraints = "South";
}
super.addLayoutComponent(comp, constraints);
}
}
You could make an JPanel and put a JTextField and the JButtons inside it. That's was soulution, when I had the same problem.
EDIT:
Arrowbuttons can you create with:
new javax.swing.plaf.basic.BasicArrowButton(SwingConstants.NORTH);
Where SwingConstants.NORTH says that the arrow in the button is pointing upwards
I have created a divider in JSplitPane. I am unable to set the color of divider. I want to set the color of divider. Please help me how to set color of that divider.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SplitPaneDemo {
JFrame frame;
JPanel left, right;
JSplitPane pane;
int lastDividerLocation = -1;
public static void main(String[] args) {
SplitPaneDemo demo = new SplitPaneDemo();
demo.makeFrame();
demo.frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
demo.frame.show();
}
public JFrame makeFrame() {
frame = new JFrame();
// Create a horizontal split pane.
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left = new JPanel();
left.setBackground(Color.red);
pane.setLeftComponent(left);
right = new JPanel();
right.setBackground(Color.green);
pane.setRightComponent(right);
JButton showleft = new JButton("Left");
showleft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(left, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showright = new JButton("Right");
showright.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(right, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showboth = new JButton("Both");
showboth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
c.remove(pane);
c.remove(left);
c.remove(right);
pane.setLeftComponent(left);
pane.setRightComponent(right);
c.add(pane, BorderLayout.CENTER);
if (lastDividerLocation >= 0) {
pane.setDividerLocation(lastDividerLocation);
}
c.validate();
c.repaint();
}
});
JPanel buttons = new JPanel();
buttons.setLayout(new GridBagLayout());
buttons.add(showleft);
buttons.add(showright);
buttons.add(showboth);
frame.getContentPane().add(buttons, BorderLayout.NORTH);
pane.setPreferredSize(new Dimension(400, 300));
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
pane.setDividerLocation(0.5);
return frame;
}
}
Thanks
Sunil kumar Sahoo
Or, since the divider is a container, you can do the following:
dividerContainer = (BasicSplitPaneDivider) splitPane.getComponent(2);
Component leftBtn = dividerContainer.getComponent(0);
Component rightBtn = dividerContainer.getComponent(1);
dividerContainer.setBackground(Color.white);
dividerContainer.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
dividerContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
dividerContainer.add(toolbar);
dividerContainer.setDividerSize(toolbar.getPreferredSize().height);
This code works for me:
splitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paint(g);
}
};
}
});
splitPane.setBorder(null);
You can change divider color "g.setColor(new Color(R,G,B))".
This worked for me fine.First you are creating JFrame with it's normal methods such as setDefaultCloseOperation(), setBounds(), getContentPane(). Then create an object from your class then use that to call all the other methods through out the program, in this case I created object called app. One thing you have to keep in mind is that don't forget to use ActionListener e.
Also color changes must go with setBackground() function, while you getting the values from getSource() for the color change.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main implements ActionListener {
private static void createAndShowGUI() {
Main app=new Main();
// make frame..
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("I am a JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,30,300,120);
frame.setLayout(null);
//Create a split pane
JSplitPane myPane = new JSplitPane();
myPane.setOpaque(true);
myPane.setDividerLocation(150);
app.right = new JPanel();
app.right.setBackground(new Color(255,0,0));
app.left = new JPanel();
app.left.setBackground(new Color(0,255,0));
app.left.setLayout(null);
myPane.setRightComponent(app.right);
myPane.setLeftComponent(app.left);
// make buttons
app.butt1=new JButton("Red");
app.butt2=new JButton("Blue");
app.butt3=new JButton("Green");
// add and size buttons
app.left.add(app.butt1);
app.butt1.setBounds(10,10, 100,20);
app.left.add(app.butt2);
app.butt2.setBounds(10,30, 100,20);
app.left.add(app.butt3);
app.butt3.setBounds(10,50, 100,20);
// set up listener
app.butt1.addActionListener(app);
app.butt2.addActionListener(app);
app.butt3.addActionListener(app);
frame.setContentPane(myPane);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
// check which button and act accordingly
if (e.getSource()==butt1)
right.setBackground(new Color(255,0,0));
if (e.getSource()==butt2)
right.setBackground(new Color(0,0,255));
if (e.getSource()==butt3)
right.setBackground(new Color(0,255,0));
}
public static void main(String[] args) {
// start off..
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
}
catch (Exception e)
{
System.out.println("Cant get laf");
}
Object a[]= UIManager.getInstalledLookAndFeels();
for (int i=0; i<a.length; i++)
System.out.println(a[i]);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
// application object fields
int clickCount=0;
JLabel label;
JButton butt1;
JButton butt2;
JButton butt3;
JPanel left;
JPanel right;
}