FlowLayout not going to new line - java

I'm trying to add a variable number of JPanels (each one containst 2 Label) inside another JPanel using the FlowLayout.
When there's too many panels added instead of going to the new row they disappear out of the border
I've tried many types of Layouts, setting sizes, maximussizes but nothing changes.
public class AlbumView extends javax.swing.JFrame
{
private Album A;
public AlbumView()
{
initComponents();
A = new Album();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = this.getSize().width;
int h = this.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
this.setLocation(x, y);
pnlCategorie.setLayout(new FlowLayout(FlowLayout.TRAILING, 10, 10));
/*
Insert of many elements in the Album
*/
aggiornaAlbum();
}
public void aggiornaAlbum()
{
for(int i = 0; i < A.getDim(); i++)
{
Categoria c = A.getCategoria(i);
JPanel pnl = new JPanel();
pnl.setName(c.getNome());
JLabel lb1, lb2;
ImageIcon img = new ImageIcon(c.getPhoto(0).getImg(95, 95)); //da cambiare lo 0 con un numero casuale tra le foto disponibili
lb1 = new JLabel(img, JLabel.CENTER);
lb2 = new JLabel(c.getNome(), JLabel.CENTER);
pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));
pnl.setBorder(BorderFactory.createLineBorder(Color.black));
pnl.add(lb1);
pnl.add(lb2);
//pnl.revalidate();
//pnl.repaint();
pnlCategorie.add(pnl);
}
//ADDED AFTER COMMENT, NOTHING CHANGED (but probably it's because i didn't get exaclty what to do
pnlCategorie.revalidate();
pnlCategorie.repaint();
}
pnlCategorie is created using NetBeans swing.
I expect that after the number of jpanels that fits the bigger jPanel the next one goes to a new line
Example of what is appearing (I'm using some exaple image, don't judge) :

Related

How to show matrix in a JFrame with JLabels

I want to show a matrix in Java in a JFrame, I know how to do it, but I have this problem now, and I donĀ“t know how to solve it. I've tried a lot of things, but nothing has worked.
The problem are these empty places marked in the picture.
code:
public class VentanaConsulta extends javax.swing.JFrame {
JLabel[] arreglo = new JLabel[16];
public VentanaConsulta(Sistema sistema, VentanaInicial ventanaInicial) {
this.modelo = sistema;
this.ventanaInicial = ventanaInicial;
initComponents();
IniciarComponentes();
}
private void IniciarComponentes() {
int[][] campo = {{1,2,3,4}, {0,0,0,0} , {0,0,0,0}, {0,0,0,0}};
setLayout(new GridLayout(4, 4));
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
arreglo[i] = new JLabel(Integer.toString(campo[i][j]));
arreglo[i].setHorizontalAlignment(SwingConstants.CENTER);
add(arreglo[i]);
}
}
}
Your image shows that while you're setting the layout of your container to a 4x4 grid, you are adding more than 16 items to this container, and this is likely due to your setting the layout of the wrong container. You are probably setting the layout of the main JFrame's contentPane, adding your JLabels to it, and adding other things to it as well, messing up the size of the grid.
I suggest that you create a new JPanel, one to hold your JLabel grid, give it a 4x4 grid layout, add the JLabels, and then add this JPanel to the main GUI (the JFrame), or to a container that is displayed within the JFrame.
And yes, your arreglo array indices use is wrong, since you are trying to add a whole row to a single array item. e.g. something like:
private void IniciarComponentes() {
int[][] campo = {{1,2,3,4}, {0,0,0,0} , {0,0,0,0}, {0,0,0,0}};
JPanel gridPanel = new JPanel(new GridLayout(4, 4));
// setLayout(new GridLayout(4, 4));
for (int i = 0; i < campo.length; i++) { // avoid using "magic" numbers
for (int j = 0; j < campo[i].length; j++) {
JLabel label new JLabel(Integer.toString(campo[i][j]));
label.setHorizontalAlignment(SwingConstants.CENTER);
arreglo[4 * i + j] = label
gridPanel.add(label);
}
}
// here add gridPanel to the main GUI
}

How to make a JPanel into a BufferedImage Java

I have a half-working paint/turtle graphics program but I am having a few issues.
I am going to need to save the image that is drawn at some point - I know I need to use a BufferedImage but how do I go about this? I have attached a little bit of my code below.
In short I have a JFrame with a text field and a white JPanel below it. When commands are typed in by the user lines are drawing through another class and appear on the JPanel. I know I won't be able to save them off the JPanel to an image but have no understanding of how to implement a buffered image and what i would/wouldn't need to change.
Please be kind, I am new to programming and haven't finished some parts of my code yet.
Thanks in advance
public class Turtle2 extends JFrame implements ActionListener, KeyListener{
JMenuBar menuBar;
JMenu help, file;
JPanel panel, panel2;
JMenuItem newO, load, save, exitO, about;
JTextField text;
int savecounter = 0, newcounter = 1, part2I = 0;
int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
int trigger = 1, turnleftconstant = 0, turnrightconstant =0, direction =0;
int col = 0;
public Turtle2() {
setLayout(new FlowLayout());
setSize(1000, 1000);
setTitle("Graphic");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//menu bar
//sets up general look of window
panel = new JPanel();
panel.setBackground(Color.darkGray);
//implements box layout
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
//sets up drawing area
panel2 = new JPanel();
panel2.setPreferredSize(new Dimension(500, 500));;
panel2.setBackground(Color.WHITE);
panel2.setBorder(BorderFactory.createLineBorder(Color.darkGray, 3));
//starting point on drawing area co-ordinates
x1 = 15; x2 = 15; y1 = 230; y2 =230;
//starting point implemented
LinePen first = new LinePen(x1, y1, x2, y2, col);
panel2.add(first);
//sets up user input text box
text = new JTextField(30);
//add action listener to text box - ready for input and details responses
text.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//retrieves user input
String actions = text.getText();
first.setVisible(true);
//commands from text
//add the command line textfeild to the interface
panel.add(text);
//uses border layout to set the layout of the interface
getContentPane().add(BorderLayout.NORTH, panel);
getContentPane().add(BorderLayout.CENTER, panel2);
//set the size of the interface
setSize(600,600);
//ensure the interface is visible
setVisible(true);
}
I would keep an array of all your lines, then iterate through them, and then use img.createGraphics() to draw your lines and other graphics.

Improper sizing using GridBagLayout

I am trying to use a GridBagLayout to have a JFrame that contains a JPanel that has a grid layout and a JPanel with just a large button. I want the rows to all be the same size, and the JPanel with the JButton to be the same size as one row. However, the button panel, which is currently empty, is about 1/3 of the JFrame. I'm not quite sure what's happening, but it is pretty important to me that I maintain this structure because the rest of my code uses this. Any help is appreciated, and thank you in advance.
This is my code:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class Minesweeper extends JPanel {
private final int SIZE = 7;
public void startGame(){
JFrame holder = new JFrame();
JPanel window = new JPanel();
JPanel pan = new JPanel();
holder.setLayout(new GridBagLayout());
GridBagConstraints con = new GridBagConstraints();
con.weightx = 1;
con.weighty = 1;
con.gridx = 0;
con.gridy = 0;
con.fill = GridBagConstraints.BOTH;
con.gridheight = SIZE;
con.gridwidth = SIZE;
holder.getContentPane().setBackground(Color.darkGray);
holder.setSize(450, 450);
holder.setResizable(false);
holder.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBackground(Color.darkGray);
window.setLayout(new GridLayout(SIZE, SIZE));
for (int c=0; c<(SIZE*SIZE); c++){
int row = (c/SIZE);
int col = (c%SIZE);
JPanel p = new JPanel();
p.setBackground(Color.gray);
Border b = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
p.setBorder(b);
window.add(p);
}
holder.add(window, con);
con.gridx = 0;
con.gridy = SIZE+1;
con.gridheight = 0;
con.gridwidth = SIZE;
holder.add(pan, con);
holder.setVisible(true);
}
public static void main(String[] args){
Minesweeper start = new Minesweeper();
start.startGame();
}
}
This is what is being shown:
con.gridy = SIZE+1;
You can't specify a gridy value of 8. There are only two components added to the grid. The grid doesn't know that one of your panels happens to contain 7 rows of components. So the value should be 1.
This won't solve the problem but should clear up a misunderstanding of how GridBagLayout works.
holder.setSize(450, 450);
You are manually setting a size to the frame. Each component is originally sized at its preferred size. When there is extra space in the frame the space is distributed equally between the two components.
You should NOT be setting the size. Each component should determine its own size and then you should use pack(). So you need to use custom components that override the getPreferredSize() method to return the appropriate size for each component so pack() can do its job.
Also, the pack() is done just before the setVisible().

JList is showing duplicates

I am working on a small example using Java Swing where I want to draw a sine graph on one panel and the co-ordinates of the graph in another panel. So I created a class that extends the JFrame then I created the JPanel for graph and co-ordinates. For displaying co-ordinates I am using JList. Now the problem is the co-ordinates are showing duplicate values. Here is my code:
public class MyFrame extends JFrame {
JList list;
DecimalFormat df = new DecimalFormat("#.###");
DefaultListModel model = new DefaultListModel();
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyFrame frame = new MyFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 600, 600);
contentPane = new JPanel();
contentPane.setBorder(new LineBorder(new Color(0, 0, 0)));
setContentPane(contentPane);
contentPane.setLayout(new GridLayout(1, 2, 0, 0));
JPanel panel = new MyGraph();
panel.setBorder(new LineBorder(new Color(0, 0, 0)));
contentPane.add(panel);
list = new JList(model);
list.setVisibleRowCount(4);
JPanel panel_1 = new JPanel();
panel_1.setBorder(new LineBorder(new Color(0, 0, 0)));
panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS));
JLabel lblNewLabel_1 = new JLabel("X - Y");
panel_1.add(lblNewLabel_1);
JScrollPane slistScroller = new JScrollPane(list);
panel_1.add(slistScroller);
contentPane.add(panel_1);
}
class MyGraph extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
int xBase = 10;
int top = 100;
int yScale = 10;
int xAxis = 360;
int yBase = top + yScale;
g.drawLine(xBase, top, xBase, top + 2 * yScale);
g.drawLine(xBase, yBase, xBase + xAxis, yBase);
g.setColor(Color.red);
int x2=0, y2=0;
int x1 = xBase + 0;
int y1 = yBase - (int) (10*Math.sin(0) * yScale);
int i;
for (i = 0; i < 10; i++) {
x2 = xBase + i;
y2 = yBase - (int) (10*Math.sin(i) * yScale);
g.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
df = new DecimalFormat("#.###");
model.addElement(i +" -- " + df.format(10*Math.sin(i)));
}
model.addElement("------END----------");
}
}
}
Here is the output of my program:
As per my program, I have a for loop from angles 0 to 10 and I am adding the values to DefaultListModel model which is added to JList list.
Can someone please help me where I am doing mistake in this code?
Also even when I have this line list.setVisibleRowCount(4); , I was expecting only 4 records displayed to the user with a scroll-bar, but as per the output image it is not working like that.
paintComponent may be any number of times, for any number of reasons, try resizing the frame and see what happens.
Your paint method should focus on doing just that, painting.
You need to change the process so that the paintComponent becomes depend on the model, not the other way round.
Take a look at Painting in AWT and Swing for more details about painting in Swing.
You may also want to consider using a ListCellRender to render the data in the model in the JList, this way, you could more easily share the model and it's data.
See Writing a Custom Cell Renderer for more details

How to divide an applet/frame into two parts using panel and perform events between them [duplicate]

This question already has answers here:
Resizing issue with canvas within jscrollpane within jsplitpane
(3 answers)
Closed 8 years ago.
The program i want to make is
Divide an applet/frame(awt) into two parts using panel. The first panel contains four buttons naming ellipse, rectangle, circle and triangle. Taking one button and asking coordinates and make a figure on the other panel.
Please someone explain me the concept or working because im not good at layouts and know methods to use to convey from one panel to other..
Thank you very much
I would recommend starting out with a layout manager.. if you want 2 JPanels next to each other, you can use the GridLayout layout manager. It takes 2 arguments, and one of it's overloaded constructors takes 4 arguments.
setLayout(new GridLayout(rows, columns)); //one commonly used constructor
setLayout(new GridLayout(rows, columns, horizontalSpacePixels, verticleSpace));
GridLayout, when used will reshape to fit the largest component, and make each part of the grid an equal size-- however this isn't the case when you use a GridLayout inside of a GridLayout (the inner GridLayout might be too big to fit within the confines that the outer GridLayout puts on it.). If I simply do
JFrame jf = new JFrame("Laying the grid out");
jf.setLayout(new GridLayout(5, 5));
JPanel[] jp = new JPanel[25];
JLabel[] jl = new JLabel[25];
for(int i = 0; i < 25; i++) {
jp[i] = new JPanel();
jp[i].setBackground(Color.YELLOW);
jl[i] = new JLabel("This is label no. " + (i+1));
jp[i].add(jl[i]);
}
//now to add all 25 components in the 5x5 grid; you simply add them, and it
//automatically positions the jpanels in the order that you place them.. left to right.
for(int i = 0; i < 25; i++)
jf.add(jp[i]);
Here is an example program that involves a simple GridLayout, and an actionListener that responds to button events by changing one of the JPanel's color.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Gui {
private JPanel p2;
private JLabel side2;
private JFrame jf;
public static void main(String[] args){
new Gui();
}
public Gui(){
jf = new JFrame("Holds 2 panels side by side.");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(new GridLayout(1, 2));
JPanel p1 = new JPanel();
p2 = new JPanel();
p1.setBackground(Color.BLACK);
p2.setBackground(Color.BLACK);
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
JLabel[] space = new JLabel[20];
for(int i = 0; i < 20; i++)
space[i] = new JLabel(" ");
JButton jb1 = new JButton("Button 1");
JButton jb2 = new JButton("Button 2");
jb1.addActionListener(new BListen());
jb2.addActionListener(new BListen());
p1.add(space[0]);
p1.add(jb1);
p1.add(space[1]);
p1.add(jb2);
p1.add(space[2]);
jf.add(p1);
side2 = new JLabel("Change the color here with the buttons there.");
side2.setForeground(Color.GREEN);
p2.add(side2);
jf.add(p2);
jf.setSize(600, 200);
jf.setVisible(true);
}
private class BListen implements ActionListener {
public void actionPerformed(ActionEvent e) {
String buttonClicked = e.getActionCommand();
if(buttonClicked.equals("Button 1")) {
JOptionPane.showMessageDialog(null, "You pressed Button 1.");
p2.setBackground(Color.BLUE);
side2.setForeground(Color.MAGENTA);
jf.setVisible(true);
}
else if(buttonClicked.equals("Button 2")) {
JOptionPane.showMessageDialog(null, "You pressed Button 2.");
p2.setBackground(Color.ORANGE);
side2.setForeground(Color.DARK_GRAY);
jf.setVisible(true);
}
}
}
}

Categories