How to put an image into jpanel with GridBagLayout()? - java

Currently, the code is:
JFrame frame = new JFrame("App");
frame.setSize(1200, 800);//Give it a size
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//Make it go away on close
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //TU ZMIENIAC
frame.add(panel);//Add it to your frame
(...)
JPanel panelForm = new JPanel(new GridBagLayout());
panel.add(panelForm);
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(10,10,10,10);
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.LINE_END;
(...)
panelForm.add(label_pageCount, c);
c.gridy++;
try {
URL url = new URL(JSONLists.thumbnail.get(page));
BufferedImage image = ImageIO.read(url);
JLabel label = new JLabel(new ImageIcon(image));
panelForm.add(label);
} catch (Exception exp) {
exp.printStackTrace();
}
Which results in:
Every Jlabel is put properly in its place on the grid, except the image which appears in top right corner instead of assigned place.

In this part:
try {
URL url = new URL(JSONLists.thumbnail.get(page));
BufferedImage image = ImageIO.read(url);
JLabel label = new JLabel(new ImageIcon(image));
panelForm.add(label); //here
} catch (Exception exp) {
exp.printStackTrace();
}
you add the component to the container without the GridBagConstratints. That's why the component is not being added in the proper location. So, changing it to:
panelForm.add(label,c); //Add with constraints
will fix it.

Related

Cannot render video from BufferedImage using HashMap in Java

In my project, I have got a class FramesUtil which contains a set of frames stored in a HashMap -
ConcurrentHashMap<Integer, Frame> frameMap
I have another class Arbiter.java that should render video using frames from frameMap.
However, I can only see the first frame when the playVideo() method is being called from Arbiter.java.
public static void main(String[] args) {
try {
FramesUtil.ensureExistence();
FrameReader reader = new FrameReader();
reader.readBinary();
playVideo();
} catch (Exception e) {
e.printStackTrace();
}
}
Looks like the JFrame is not getting updated with new BufferedImage in the loop during the iteration
Below is my playVideo method from Arbiter.java -
public static void playVideo() {
BufferedImage img;
JFrame frame = new JFrame();
GridBagLayout gLayout = new GridBagLayout();
frame.getContentPane().setLayout(gLayout);
JLabel lbIm1;
for(int i=0; (img=FramesUtil.frameMap.get(i).bufferedImage)!=null; i++) {
lbIm1 = new JLabel(new ImageIcon(img));
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.CENTER;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
System.out.println(lbIm1);
frame.getContentPane().add(lbIm1, c);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
PS. I have tried creating new JFrame and GridBagLayout instances inside the for loop

Why isn't the JPanel showing the ImageIcon?

I have a GridBagConstraints gbcImage and a JLabel that is initialized like this:
gbcImage.gridx = 1; // column 0
gbcImage.gridy = 2; // row 2
gbcImage.ipady = 100;
gbcImage.ipadx = 100;
JLabel label = new JLabel("", null, JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.WHITE);
panel.add(label, gbcImage);
Where panel is added to a JFrame.
So I implemented a MouseListener to the label:
public void mouseClicked(MouseEvent e) {
JFileChooser jfc = new JFileChooser();
int iRet = jfc.showOpenDialog(panel);
if (iRet == jfc.APPROVE_OPTION)
{
File file = jfc.getSelectedFile();
try
{
BufferedImage bi = ImageIO.read(file);
image = new ImageIcon(bi);
JLabel label = new JLabel("", image, JLabel.CENTER);
panel.add(label, gbcImage);
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
}
But it didn't work. The image doesn't show in the panel at runtime.
What am I missing?
There is no need to create a new JLabel. The problem is you added a new label to the panel but its default size is (0, 0) because you didn't reavalidate() and repaint() the panel.
There is no need to create a new label.
Instead you keep a reference to the original label (like you do for the panel) and then you just replace the icon:
image = new ImageIcon(bi);
label.setIcon( image );

Java layout when using JScrollPane

This is my code
private static KeyEvent e;
private static String text1 = null;
private static String text = null;
public fysikdel() {
super("Fysikformler");
setSize(700, 502);
setDefaultCloseOperation(EXIT_ON_CLOSE);
init();
setResizable(true);
setVisible(true);
}
public void init() {
JPanel main = new JPanel();
JPanel p = new JPanel();
CardLayout c1 = new CardLayout();
JScrollPane scrollpane = new JScrollPane(p);
JPanel Mekanik = new JPanel();
p.setSize(700, 502);
Mekanik.setLayout(new FlowLayout());
//637*237
ImageIcon likformigrorelsei = new ImageIcon();
JLabel likformigrorelsel = new JLabel();
ImageIcon lagesenergii = new ImageIcon();
JLabel lagesenergil = new JLabel();
ImageIcon a = new ImageIcon();
JLabel aa = new JLabel();
ImageIcon b = new ImageIcon();
JLabel bb = new JLabel();
try {
likformigrorelsei = new ImageIcon(new URL("http://i.imgur.com/TZFkXYa.jpg"));
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
likformigrorelsel.setIcon(likformigrorelsei);
try {
lagesenergii = new ImageIcon(new URL("http://i.imgur.com/TZFkXYa.jpg"));
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
lagesenergil.setIcon(lagesenergii);
try {
a = new ImageIcon(new URL("http://i.imgur.com/TZFkXYa.jpg"));
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
aa.setIcon(a);
try {
b = new ImageIcon(new URL("http://i.imgur.com/TZFkXYa.jpg"));
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
bb.setIcon(b);
Mekanik.add(likformigrorelsel);
Mekanik.add(lagesenergil);
Mekanik.add(aa);
Mekanik.add(bb);
JPanel Tryck = new JPanel();
main.setLayout(new GridLayout(1,1));
p.setLayout(c1);
this.add(main);
main.add(scrollpane);
p.add(Mekanik, "1");
p.add(Tryck, "2");
c1.show(p, "1");
When I add more pictures I want them to fill up from left to right untill one row is filled, then fill the next row. At the moment it just continue to fill the first row.
If I add
scrollpane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER);
it just removes the horizontal scroll bar but the pictures are still ending up on one row.
I dont know what is wrong. Thanks for any help!
So you put all your images in the Mekanik panel, which uses a FlowLayout. As the java tutorial states,
The FlowLayout class puts components in a row, sized at their preferred size
which is obviously not what you want. So you'll have to change the layout used by your panel.
To my mind, the GridLayout would be a better fit for your problem.

Making scrolls in GridBagLayout

Good time of the day, I'm trying to add scrolls to the GridBagLayout but definitely missing the correct way to do it.
The code:
public GUI(Map map)
{
//declare image icons and try to read them
ImageIcon missing = new ImageIcon();
ImageIcon wall = new ImageIcon();
ImageIcon floor = new ImageIcon();
//set texture for missing cases
try
{
Image tempImage = ImageIO.read(this.getClass().getResource("/resources/images/missing.png"));
missing = new ImageIcon(tempImage.getScaledInstance(16, 16, Image.SCALE_DEFAULT));
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
Image tempImage = ImageIO.read(this.getClass().getResource("/resources/images/wall.png"));
wall = new ImageIcon(tempImage.getScaledInstance(16, 16, Image.SCALE_DEFAULT));
tempImage = ImageIO.read(this.getClass().getResource("/resources/images/floor.png"));
floor = new ImageIcon(tempImage.getScaledInstance(16, 16, Image.SCALE_DEFAULT));
}
catch(Exception e)
{
e.printStackTrace();
}
Container pane = getContentPane();
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
for (int i=0;i<map.getMapSize();i++)
{
for (int j=0;j<map.getMapSize();j++)
{
c.gridy=i;
c.gridx=j;
if (i==0 && j==0)
{
c.weightx=1;
c.weighty=1;
}
else
{
c.weightx=0;
c.weighty=0;
}
c.gridwidth=1;
c.gridheight=1;
c.fill = GridBagConstraints.BOTH;
JLabel tile = new JLabel(missing);
if (map.getElementAt(i, j)==0)
{
tile.setIcon(wall);
}
else
{
tile.setIcon(floor);
}
pane.add(tile, c);
}
}
//c.gridx=map.getMapSize();
JScrollPane thePane = new JScrollPane();
pane.add(thePane, c);
setTitle("Game GUI");
setSize(640, 480);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
As far as I understand adding JScrollPane just after filling the pane is incorrect and of course it fails. The question is: how to add them correctly in this case? The aim overall I'm trying to achieve is to be able to scroll (move) the map in the game if it exceeds the game window size.
Thanks in advance:)
I guess the issue is that you try to add the GridBagConstraints to the JScollPane instead of adding your JPanel....
JScrollPane thePane = new JScrollPane();
pane.add(thePane, c);
try this:
JPanel myMapPanel = new Jpanel();
myMapPanel.setLayout(new GridBagLayout());
// add all the stuff to myMapPanel here (do the looping stuff here)
JScrollPane thePane = new JScrollPane(myMapPanel);
pane.add(thePane, c);
take care of this:
new JScrollPane(myMapPanel);

Line up swing components by edges

Is it possible to line up swing components?
The components are in separate panels which both use flow layout. These two panels are in another panel which is using a grid layout.
As you can see there is a subtle difference and I find it annoying. I know that all of the jlabels [the rectangles in blue/purple all have the same size, so i think it might be because of the '+' and '*', but I'm not sure because the left sides of the first two boxes aren't lined up.
the panels
JPanel panel2 = new JPanel(new GridLayout(4, 1));
JPanel panel2a = new JPanel(new FlowLayout());
JPanel panel2b = new JPanel(new FlowLayout());
the first two rectangles (purple)
add1 = new JLabel("", JLabel.CENTER);
add1.setTransferHandler(new TransferHandler("text"));
add1.setBorder(b2);
add2 = new JLabel("", JLabel.CENTER);
add2.setTransferHandler(new TransferHandler("text"));
add2.setBorder(b2);
the two blue rectangles
textFieldA = new JTextField();
textFieldA.setHorizontalAlignment(JTextField.CENTER);
textFieldA.setEditable(false);
textFieldA.setBorder(new LineBorder(Color.blue));
textFieldM = new JTextField();
textFieldM.setHorizontalAlignment(JTextField.CENTER);
textFieldM.setEditable(false);
textFieldM.setBorder(new LineBorder(Color.blue));
the + and *
opA = new JLabel("+", JLabel.CENTER);
opS = new JLabel("*", JLabel.CENTER);
Showing that the rectangles are the same size
Dimension d = card1.getPreferredSize();
int width = d.width + 100;
int height = d.height + 50;
add1.setPreferredSize(new Dimension(width, height));
add2.setPreferredSize(new Dimension(width, height));
mult1.setPreferredSize(new Dimension(width, height));
mult2.setPreferredSize(new Dimension(width, height));
textFieldA.setPreferredSize(new Dimension(width, height));
textFieldM.setPreferredSize(new Dimension(width, height));
Adding to the panels
panel2a.add(add1);
panel2a.add(opA);
panel2a.add(add2);
panel2a.add(enterA);
panel2a.add(textFieldA);
panel2c.add(mult1);
panel2c.add(opM);
panel2c.add(mult2);
panel2c.add(enterM);
panel2c.add(textFieldM);
panel2.add(panel2a);
panel2.add(panel2c);
AFAIU this could be achieved using GroupLayout. This layout would require 5 horizontal groups and 2 vertical groups.
See How to Use GroupLayout for examples (including discussion of that image).
See also this answer for an MCVE.
Cross container layout management isn't really possible (or at least I've never seen a layout manager that does it).
You can, however, think carefully about your layout requirements and produce some interesting effects using compound components and layout managers...
public class TestLayout {
public static void main(String[] args) {
new TestLayout();
}
public TestLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 0));
frame.add(new CalculatePane("+"));
frame.add(new CalculatePane("x"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CalculatePane extends JPanel {
public CalculatePane(String operator) {
setLayout(new GridBagLayout());
Font font = UIManager.getFont("TextField.font").deriveFont(Font.BOLD, 24);
JTextField field1 = new JTextField(2);
JTextField field2 = new JTextField(2);
JTextField field3 = new JTextField(2);
field1.setFont(font);
field2.setFont(font);
field3.setFont(font);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.fill = GridBagConstraints.BOTH;
add(field1, gbc);
gbc.gridx++;
add(new JLabel(operator), gbc);
gbc.gridx++;
add(field2, gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(new JButton("="), gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx++;
add(field3, gbc);
}
}
}

Categories

Resources