Would anyone mind having a look at these bits of code and see if there is a memory leak in them, it isn't going to be overly large but my program keeps crashing after a while of running and I don't know how to use viualvm even though I have been reading up on it for several days now and haven't the slightest idea what I am looking for in the heap dumps and so on. thanks for your help,
ps I know I have posted far to muchg code but i dont know what else to do so that you can hopefully see where the problem arises for me. If it helps I can email you the full program to take a look at. Thanks very much for any help you can give.
public class extraScreenPanel {
static JPanel screenPanel = new JPanel(new BorderLayout());
public static JPanel extraScreenPanel(int dispNum)
{
JLabel label = new JLabel("" + dispNum + "");
label.setPreferredSize(new Dimension(800, 600));
label.setVerticalAlignment( SwingConstants.TOP );
screenPanel = imgDisp(dispNum);
label.setForeground(Color.white);
label.setFont(new Font("Serif", Font.BOLD, 200));
screenPanel.add(label, BorderLayout.PAGE_END );
return screenPanel;
}
public static JPanel imgDisp(int picNum) {
String ref = "C:/PiPhotoPic/pic16.jpg";;
BufferedImage loadImg = loadImage(ref);
JImagePanel panel = new JImagePanel(loadImg, 0, 0);
panel.setPreferredSize(new Dimension(800, 600));
return panel;
}
public static class JImagePanel extends JPanel{
private BufferedImage image;
int x, y;
public JImagePanel(BufferedImage image, int x, int y) {
super();
this.image = image;
this.x = x;
this.y = y;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, x, y, null);
}
}
public static BufferedImage loadImage(String ref) {
BufferedImage bimg = null;
try {
bimg = javax.imageio.ImageIO.read(new File(ref));
} catch (Exception e) {
e.printStackTrace();
}
BufferedImage bimg2 = resize(bimg,800,600);//set these to the resolution of extra screens
return bimg2;
}
public static BufferedImage resize(BufferedImage img, int newW, int newH) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
}
Another part of the method
public class piPhoto
{
static int mostRecent = 0;
static int dispNum = 0;
static int lastDisp = 0;
static JPanel picPanel = imgDisp.imgDisp(dispNum);
static JFrame frame = new JFrame("Pi Photography");
static JPanel cornerPanel = new JPanel();
static JPanel bottomPanel = new JPanel();
static JPanel menuPanel = new JPanel(new BorderLayout());
static JPanel currentNumPanel = currentNumDisp.currentNumDisp(dispNum);
static JPanel printPanel = printOptions.printOptions();
static JPanel buttonPanel = updateButtonPanel.updateButtonPanel(mostRecent);
static JPanel screen1Panel = new JPanel();
static JPanel screen2Panel = new JPanel();
static JPanel screen3Panel = new JPanel();
static JPanel screen4Panel = new JPanel();
static JPanel screenPanel12 = new JPanel(new BorderLayout());
static JPanel screenPanel123 = new JPanel(new BorderLayout());
static JPanel screenPanel1234 = new JPanel(new BorderLayout());
static JPanel screensPanel = new JPanel(new BorderLayout());
static JPanel deskScreen = new JPanel();
static JPanel wholePanel = new JPanel(new BorderLayout());
static JPanel wholePanel2 = new JPanel(new BorderLayout());
public static void launchPiPhoto()
{
launchNC4.launch();
bottomPanel.setPreferredSize(new Dimension(1440, 200));
buttonPanel.setPreferredSize(new Dimension(1120, 200));
cornerPanel.setPreferredSize(new Dimension(300,200));
screen1Panel.setPreferredSize(new Dimension(800,600));
screen2Panel.setPreferredSize(new Dimension(800,600));
screen3Panel.setPreferredSize(new Dimension(800,600));
screen4Panel.setPreferredSize(new Dimension(800,600));
screensPanel.setPreferredSize(new Dimension(3200,600));
deskScreen.setPreferredSize(new Dimension(800,600));
wholePanel.setPreferredSize(new Dimension(4640,900));
wholePanel2.setPreferredSize(new Dimension(5440,900));
cornerPanel.setLayout(new BoxLayout(cornerPanel, BoxLayout.PAGE_AXIS));
picPanel.setPreferredSize(new Dimension(1120, 620));
//Menu Panel Set-up
cornerPanel.add(currentNumPanel);
bottomPanel.add(buttonPanel);
bottomPanel.add(cornerPanel);
menuPanel.setPreferredSize(new Dimension(1440, 840));
menuPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
menuPanel.add(bottomPanel, BorderLayout.PAGE_END);
menuPanel.add(picPanel, BorderLayout.LINE_START);
menuPanel.add(printPanel, BorderLayout.LINE_END);
screen1Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 3);
screen2Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 2);
screen3Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 1);
screen4Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent);
screenPanel12.add(screen1Panel, BorderLayout.LINE_START);
screenPanel12.add(screen2Panel, BorderLayout.LINE_END);
screenPanel123.add(screenPanel12, BorderLayout.LINE_START);
screenPanel123.add(screen3Panel, BorderLayout.LINE_END);
screenPanel1234.add(screenPanel123, BorderLayout.LINE_START);
screenPanel1234.add(screen4Panel, BorderLayout.LINE_END);
screensPanel.add(screenPanel1234, BorderLayout.LINE_END);
deskScreen = extraScreenPanel.extraScreenPanel(dispNum);
wholePanel.add(menuPanel, BorderLayout.LINE_START);
wholePanel.add(screensPanel, BorderLayout.LINE_END);
wholePanel2.add(wholePanel, BorderLayout.LINE_START);
wholePanel2.add(deskScreen, BorderLayout.LINE_END);
frame.add(wholePanel2);
//Frame set-up and Initializing
JFrame.setDefaultLookAndFeelDecorated(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
newImageRecieved.runCheck();
}
public static void repaintButtonPanel()
{
bottomPanel.removeAll();
bottomPanel.setPreferredSize(new Dimension(1440, 200));
buttonPanel = updateButtonPanel.updateButtonPanel(mostRecent);
buttonPanel.setPreferredSize(new Dimension(1120, 200));
cornerPanel.add(currentNumPanel);
bottomPanel.add(buttonPanel);
bottomPanel.add(cornerPanel);
menuPanel.add(bottomPanel, BorderLayout.PAGE_END);
frame.validate();
}
public static void repaintScreens()
{
wholePanel.remove(screensPanel);
screen1Panel.removeAll();
screen1Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent);
screen2Panel.removeAll();
screen2Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 1);
screen3Panel.removeAll();
screen3Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 2);
screen4Panel.removeAll();
screen4Panel = extraScreenPanel.extraScreenPanel(piPhoto.mostRecent - 3);
screenPanel12.add(screen1Panel, BorderLayout.LINE_START);
screenPanel12.add(screen2Panel, BorderLayout.LINE_END);
screenPanel123.add(screenPanel12, BorderLayout.LINE_START);
screenPanel123.add(screen3Panel, BorderLayout.LINE_END);
screenPanel1234.add(screenPanel123, BorderLayout.LINE_START);
screenPanel1234.add(screen4Panel, BorderLayout.LINE_END);
screensPanel.add(screenPanel1234, BorderLayout.LINE_END);
wholePanel.add(menuPanel, BorderLayout.LINE_START);
wholePanel.add(screensPanel, BorderLayout.LINE_END);
frame.validate();
}
}
the part that checks to see if new images are added to the file yet
public class newImageRecieved {
static int count = 0;
public static void runCheck()
{
int delay = 500;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
newImageRecieved(piPhoto.mostRecent+1);
}
};
new Timer(delay, taskPerformer).start();
}
public static void newImageRecieved(int picNum)
{
String url[] = new String[5000];
String part1;
url[0] = "C:/PiPhotoPic/pic16.jpg";
for(Integer i=1;i<5000;i++){
if(i<10){part1 = "C:/temp/new0000000";}
else if(i<100){part1 = "C:/temp/new000000";}
else if(i<1000){part1 = "C:/temp/new00000";}
else {part1 = "C:/temp/new00000";}
String num = Integer.toString(i);
url[i]= part1 + num + ".jpg";
}
if(picNum<0){picNum=0;}
String ref = url[picNum];
piPhoto.frame.validate();
boolean exists = (new File(ref)).exists();
if(exists == true)
{
while (exists == true)
{
piPhoto.updateMostRecent(picNum);
ref = url[picNum + 1];
picNum = picNum + 1;
exists = (new File(ref)).exists();
}
piPhoto.updateMostRecent(picNum-1);
piPhoto.repaintButtonPanel();
piPhoto.repaintScreens();
count=0;
}
// }
}
}
You might try a memory profiler such as YourKit
Solved it today. Turns out I didnt remove the image panels from the old method, aso that when i was repainting them I was painting over the old ones and the old ones were still there. So I just needed to add in removeAll() for all the panels that were being updated and the program ran fine without heapstack errors.
Well, you are creating an array of 5000 strings and start fill up most of them.
Related
The problem: I have no control on implementing more into the histogram package, so I create an array of buttons and overlay them on top of the histogram using JLayeredPane. However, I cannot get both the histogram plot and the buttons panels to scale when the JFrame is enlarged or contracted.
The JLayedPane is composed of 2 JPanels, see MWE.
To repeat the issue, just run program and extend JFrame.
I have read the following on SO posts; jlayeredpane-with-gridlayout, jlayeredpane-with-a-layoutmanager, jlayeredpane-not-resizing-with-jframe, resize-jframe-to-jpanels-inside-jlayeredpane, automatic-content-resizing-of-jlayeredpane,
as well as the Oracle page on JLayeredPane which has some examples
As useful as these links were, I still cannot get both JPanels to extend/contract with the JFrame.
Question: Is there a way to get both JPanels in the JLayeredPane to rescale without implementing a new layout? If new layout is needed, would someone please provide a MWE on how to do such?
public class FrameDemo extends JPanel {
private JLayeredPane layeredPane;
private final int width = 800;
private final int height = 800;
private String[] layerStrings = { "Yellow (0)", "Magenta (1)", "Cyan (2)", "Red (3)", "Green (4)", "Blue (5)" };
private Color[] layerColors = { Color.yellow, Color.magenta, Color.cyan, Color.red, Color.green, Color.blue };
public FrameDemo() {
setLayout(new BorderLayout());
init();
addPanels();
add(layeredPane, BorderLayout.CENTER);
}
private void init() {
this.layeredPane = new JLayeredPane();
this.layeredPane.setPreferredSize(new Dimension(width, height));
this.layeredPane.setBorder(BorderFactory.createTitledBorder("Histogram should go here"));
this.layeredPane.setLayout(new BorderLayout());
}
private void addPanels() {
this.layeredPane.add(createHistogramPanel(), BorderLayout.CENTER, new Integer(1));
this.layeredPane.add(createButtonPanel(), BorderLayout.CENTER, new Integer(0));
this.layeredPane.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
Dimension size = layeredPane.getSize(); // get size
createHistogramPanel().setSize(size); // push size through
createButtonPanel().setSize(size); // push size trhough
// otherChildOfLayers.setSize(size); // push size trhough
layeredPane.revalidate(); // revalidate to see updates
layeredPane.repaint(); // "Always invoke repaint after
// revalidate"
}
});
}
private JPanel createHistogramPanel() {
JPanel histpanel = new JPanel();
histpanel.setLayout(new GridLayout(2, 3));
for (int i = 0; i < layerStrings.length; i++) {
JLabel label = createColoredLabel(layerStrings[i], layerColors[i]);
histpanel.add(label);
}
histpanel.setOpaque(false);
histpanel.setBounds(10, 10, width, height);
return histpanel;
}
private JLabel createColoredLabel(String text, Color color) {
JLabel label = new JLabel("");
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(color);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setPreferredSize(new Dimension(120, 120));
return label;
}
private JPanel createButtonPanel() {
ButtonGroup buttons = new ButtonGroup();
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2, 3));
for (int i = 0; i < 6; i++) {
final int placer = i + 1;
JButton freshButton = new JButton();
freshButton.addActionListener(e -> {
System.out.println("Button " + placer + " clicked");
});
freshButton.setText("Button " + (i + 1));
freshButton.setOpaque(true);
freshButton.setContentAreaFilled(false);
freshButton.setBorderPainted(false);
freshButton.setBounds(new Rectangle(132, 75 + (i * 20), 40, 20));
buttonPanel.add(freshButton, null);
buttons.add(freshButton);
}
buttonPanel.setOpaque(false);
buttonPanel.setBounds(10, 10, width, height);
return buttonPanel;
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new FrameDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Your code won't work because in componentResized you're creating new panels and applying the size to them. You need to resize the existing panels added to the layered pane. This could be done by assigning histogramPanel and buttonPanel as instance variables.
I have three JPanels.
The left and right panels are hidden. Only center panel is visible by default.
When I press one button, the frame width will be increased by the right panel's width and the right panel becomes visible.
My problem is with the left panel because the frame cannot be increased in the left direction.
My solution is:
public void mousePressed(MouseEvent e) {
int frameWidth = frame.getBounds().width;
int frameHeight = frame.getBounds().height;
int panelWidth = leftPanel.getPreferredSize().width;
Point currCoords = frame.getLocationOnScreen();
if(!_leftPanelOpened) {
frame.setSize(new Dimension(frameWidth + panelWidth, frameHeight));
leftPanel.setVisible(true);
frame.setLocation(currCoords.x - panelWidth, currCoords.y);
_leftPanelOpened = true;
}
else {
leftPanel.setVisible(false);
frame.setSize(new Dimension(frameWidth - panelWidth, frameHeight));
frame.setLocation(currCoords.x + panelWidth, currCoords.y);
_leftPanelOpened = false;
}
}
It works, but the frame shortly blinks. Can I avoid this short blink?
Edit:
public class Main {
private static JPanel leftoption = new JPanel();
private static JPanel rightoption = new JPanel();
private static JFrame frame = new JFrame();
private static JPanel leftPanel = new JPanel();
private static JPanel rightPanel = new JPanel();
private static JPanel _centerPanel = new JPanel();
private static boolean _leftPanelOpened = false;
private static boolean _rightPanelOpened = false;
public static void main(String[] args) {
leftoption.setPreferredSize(new Dimension(50, 40));
leftoption.setBackground(Color.CYAN);
leftoption.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int frameWidth = frame.getBounds().width;
int frameHeight = frame.getBounds().height;
int panelWidth = leftPanel.getPreferredSize().width;
Point currCoords = frame.getLocationOnScreen();
if(!_leftPanelOpened) {
frame.setBounds(currCoords.x - panelWidth, currCoords.y, frameWidth + panelWidth, frameHeight);
leftPanel.setVisible(true);
_leftPanelOpened = true;
}
else {
leftPanel.setVisible(false);
frame.setBounds(currCoords.x + panelWidth, currCoords.y, frameWidth - panelWidth, frameHeight);
_leftPanelOpened = false;
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
});
rightoption.setPreferredSize(new Dimension(50, 40));
rightoption.setBackground(Color.ORANGE);
rightoption.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int frameWidth = frame.getBounds().width;
int frameHeight = frame.getBounds().height;
int panelWidth = rightPanel.getPreferredSize().width;
if(!_rightPanelOpened) {
frame.setSize(new Dimension(frameWidth+panelWidth, frameHeight));
rightPanel.setVisible(true);
_rightPanelOpened = true;
}
else {
rightPanel.setVisible(false);
frame.setSize(new Dimension(frameWidth-panelWidth, frameHeight));
_rightPanelOpened = false;
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
});
_centerPanel.setPreferredSize(new Dimension(300, 600));
_centerPanel.setBackground(Color.WHITE);
_centerPanel.add(leftoption);
_centerPanel.add(rightoption);
leftPanel.setPreferredSize(new Dimension(300, 600));
leftPanel.setBackground(Color.BLUE);
leftPanel.setVisible(false);
rightPanel.setPreferredSize(new Dimension(300, 600));
rightPanel.setBackground(Color.RED);
rightPanel.setVisible(false);
frame.add(leftPanel, BorderLayout.LINE_START);
frame.add(_centerPanel, BorderLayout.CENTER);
frame.add(rightPanel, BorderLayout.LINE_END);
frame.setSize(new Dimension(300, 600));
frame.getContentPane().setBackground(Color.WHITE);
frame.setVisible(true);
}
}
You can call setBounds(), which allows you to set position and size at the same time. Actually, under the hood, both setSize() and setLocation() call setBounds() in the end.
Furthermore, you can avoid calling setVisible(true) before the panel is in place.
Therefore, how about changing your method to:
if(!_leftPanelOpened) {
frame.setBounds(currCoords.x - panelWidth, currCoords.yframeWidth + panelWidth, frameHeight);
leftPanel.setVisible(true);
_leftPanelOpened = true;
}
public class FrameTest extends JFrame {
private JPanel contentPane;
private JPanel spielPane;
private JPanel infoPane;
private JButton btnStart;
private JLabel lblRunde;
private Monster monster1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FrameTest frame = new FrameTest();
frame.setVisible(true);
Monster m = new Monster();
frame.repaintSpielPanel();
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
public FrameTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
spielPane = new JPanel();
spielPane.setBounds(6, 6, 566, 566);
spielPane.setLayout(null);
spielPane.setBackground(Color.yellow);
contentPane.add(spielPane);
infoPane = new JPanel();
infoPane.setBounds(578, 6, 216, 566);
infoPane.setLayout(null);
infoPane.setBackground(Color.yellow);
contentPane.add(infoPane);
btnStart = new JButton("Start");
btnStart.setBounds(44, 6, 117, 29);
infoPane.add(btnStart);
lblRunde = new JLabel("Runde");
lblRunde.setBounds(77, 47, 61, 16);
infoPane.add(lblRunde);
monster1 = new Monster();
monster1.setVisible(true);
spielPane.add(monster1);
}
private class Monser extends JLabel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(0, 0, 10, 10);
}
}
public void repaintSpielPanel() {
spielPane.repaint();
}
}
I tried to put a Rectangle into my frame, but it isn't there. I'm just starting to program, so probably I just don't know how to get it onto the screen. Pls help!
Don't paint in a JLabel which isn't opaque. Instead do so in a JPanel.
Don't use null layouts and setBounds(...). While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Most important, you never add an instance of your drawing component, here Monser, to anything. To see that this is true, search your code for any calls to new Monser(). If a constructor isn't being called, an instance isn't going to be created.
Also note that you're creating a Monster instance, and this is a class that you've not shown us.
You're adding it to a null layout using JPanel, and so since it has no size, it won't show at all. Again, don't use null layouts.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyTest extends JPanel {
private static final Color BG = Color.yellow;
private static final int GAP = 8;
private JButton btnStart = new JButton("Start");
private JLabel lblRunde = new JLabel("Runde", SwingConstants.CENTER);
private MonsterPanel monsterPanel = new MonsterPanel(600, 600, BG);
public MyTest() {
JPanel buttonPanel = createButtonPanel();
buttonPanel.setBackground(BG);
setLayout(new BorderLayout(GAP, GAP));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
add(monsterPanel, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.LINE_END);
}
private JPanel createButtonPanel() {
JPanel btnPanel = new JPanel();
btnPanel.setBackground(BG);
JPanel gridPanel = new JPanel(new GridLayout(0, 1, 0, 5));
gridPanel.setOpaque(false);
gridPanel.add(btnStart);
gridPanel.add(lblRunde);
btnPanel.add(gridPanel);
return btnPanel;
}
private static void createAndShowGui() {
MyTest mainPanel = new MyTest();
JFrame frame = new JFrame("MyFrameTest");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MonsterPanel extends JPanel {
public static final int MONST_WIDTH = 10;
public static final Color MONST_COLOR = Color.red;
private int prefW;
private int prefH;
private int monstX = 0;
private int monstY = 0;
public MonsterPanel(int prefW, int prefH, Color bkgrnd) {
this.prefW = prefW;
this.prefH = prefH;
setBackground(bkgrnd);
}
public void setMonstXY(int x, int y) {
this.monstX = x;
this.monstY = y;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(MONST_COLOR);
g.fillRect(monstX, monstY, MONST_WIDTH, MONST_WIDTH);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
}
I am trying to get a JPanel to appear inside of another JPanel. Currently, the JPanel is in an external JFrame and loads with my other JFrame. I want the JPanel to be inside the other JPanel so the program does not open two different windows.
Here is a picture:
The small JPanel with the text logs I want inside of the main game frame. I've tried adding the panel to the panel, panel.add(othePanel). I've tried adding it the JFrame, frame.add(otherPanel). It just overwrites everything else and gives it a black background.
How can I add the panel, resize, and move it?
Edits:
That is where I want the chatbox to be.
Class code:
Left out top of class.
public static JPanel panel;
public static JTextArea textArea = new JTextArea(5, 30);
public static JTextField userInputField = new JTextField(30);
public static void write(String message) {
Chatbox.textArea.append("[Game]: " + message + "\n");
Chatbox.textArea.setCaretPosition(Chatbox.textArea.getDocument()
.getLength());
Chatbox.userInputField.setText("");
}
public Chatbox() {
panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setPreferredSize(new Dimension(380, 100));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
scrollPane
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
userInputField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String fromUser = userInputField.getText();
if (fromUser != null) {
textArea.append(Frame.username + ":" + fromUser + "\n");
textArea.setCaretPosition(textArea.getDocument()
.getLength());
userInputField.setText("");
}
}
});
panel.add(userInputField, SwingConstants.CENTER);
panel.add(scrollPane, SwingConstants.CENTER);
//JFrame frame = new JFrame();
//frame.add(panel);
//frame.setSize(400, 170);
//frame.setVisible(true);
}
Main frame class:
public Frame() {
frame.getContentPane().remove(loginPanel);
frame.repaint();
String capName = capitalizeString(Frame.username);
name = new JLabel(capName);
new EnemyHealth("enemyhealth10.png");
new Health("health10.png");
new LoadRedCharacter("goingdown.gif");
new Spellbook();
new LoadMobs();
new LoadItems();
new Background();
new Inventory();
new ChatboxInterface();
frame.setBackground(Color.black);
Frame.redHealthLabel.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setFont(new Font("Serif", Font.PLAIN, 20));
ticks.setForeground(Color.yellow);
Frame.redHealthLabel.setForeground(Color.black);
// Inventory slots
panel.add(slot1);
panel.add(name);
name.setFont(new Font("Serif", Font.PLAIN, 20));
name.setForeground(Color.white);
panel.add(enemyHealthLabel);
panel.add(redHealthLabel);
panel.add(fireSpellBookLabel);
panel.add(iceSpellBookLabel);
panel.add(spiderLabel);
panel.add(appleLabel);
panel.add(fireMagicLabel);
panel.add(swordLabel);
// Character
panel.add(redCharacterLabel);
// Interface
panel.add(inventoryLabel);
panel.add(chatboxLabel);
// Background
panel.add(backgroundLabel);
frame.setContentPane(panel);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
frame.getContentPane().repaint();
//I WOULD LIKE THE LOADING OF THE PANEL SOMEWHERE IN THIS CONSTRUCTOR.
new ResetEntities();
frame.repaint();
panel.setLayout(null);
Run.loadKeyListener();
Player.px = Connect.x;
Player.py = Connect.y;
new Mouse();
TextualMenu.rect = new Rectangle(Frame.inventoryLabel.getX() + 80,
Frame.inventoryLabel.getY() + 100,
Frame.inventoryLabel.getWidth(),
Frame.inventoryLabel.getHeight());
Player.startMessage();
}
Don't use static variables.
Don't use a null layout.
Use appropriate layout managers. Maybe the main panel uses a BorderLayout. Then you add your main component to the CENTER and a second panel to the EAST. The second panel can also use a BorderLayout. You can then add the two components to the NORTH, CENTER or SOUTH as you require.
For example, using a custom Border:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
#SuppressWarnings("serial")
public class FrameEg extends JPanel {
public static final String FRAME_URL_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2010/199/1/0/Just_Frames_5_by_ScrapBee.png";
public static final int INSET_GAP = 120;
private BufferedImage frameImg;
private BufferedImage smlFrameImg;
public FrameEg() {
try {
URL frameUrl = new URL(FRAME_URL_PATH);
frameImg = ImageIO.read(frameUrl);
final int smlFrameWidth = frameImg.getWidth() / 2;
final int smlFrameHeight = frameImg.getHeight() / 2;
smlFrameImg = new BufferedImage(smlFrameWidth, smlFrameHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics g = smlFrameImg.getGraphics();
g.drawImage(frameImg, 0, 0, smlFrameWidth, smlFrameHeight, null);
g.dispose();
int top = INSET_GAP;
int left = top;
int bottom = top;
int right = left;
Insets insets = new Insets(top, left, bottom, right);
MyBorder myBorder = new MyBorder(frameImg, insets);
JTextArea textArea = new JTextArea(50, 60);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
for (int i = 0; i < 300; i++) {
textArea.append("Hello world! How is it going? ");
}
setLayout(new BorderLayout(1, 1));
setBackground(Color.black);
Dimension prefSize = new Dimension(frameImg.getWidth(),
frameImg.getHeight());
JPanel centerPanel = new MyPanel(prefSize);
centerPanel.setBorder(myBorder);
centerPanel.setLayout(new BorderLayout(1, 1));
centerPanel.add(new JScrollPane(textArea), BorderLayout.CENTER);
MyPanel rightUpperPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
MyPanel rightLowerPanel = new MyPanel(new Dimension(smlFrameWidth,
smlFrameHeight));
top = top / 2;
left = left / 2;
bottom = bottom / 2;
right = right / 2;
Insets smlInsets = new Insets(top, left, bottom, right);
rightUpperPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightUpperPanel.setLayout(new BorderLayout());
rightLowerPanel.setBorder(new MyBorder(smlFrameImg, smlInsets));
rightLowerPanel.setBackgroundImg(createBackgroundImg(rightLowerPanel
.getPreferredSize()));
JTextArea ruTextArea1 = new JTextArea(textArea.getDocument());
ruTextArea1.setWrapStyleWord(true);
ruTextArea1.setLineWrap(true);
rightUpperPanel.add(new JScrollPane(ruTextArea1), BorderLayout.CENTER);
JPanel rightPanel = new JPanel(new GridLayout(0, 1, 1, 1));
rightPanel.add(rightUpperPanel);
rightPanel.add(rightLowerPanel);
rightPanel.setOpaque(false);
add(centerPanel, BorderLayout.CENTER);
add(rightPanel, BorderLayout.EAST);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private BufferedImage createBackgroundImg(Dimension preferredSize) {
BufferedImage img = new BufferedImage(preferredSize.width,
preferredSize.height, BufferedImage.TYPE_INT_ARGB);
Point2D center = new Point2D.Float(img.getWidth()/2, img.getHeight()/2);
float radius = img.getWidth() / 2;
float[] dist = {0.0f, 1.0f};
Color centerColor = new Color(100, 100, 50);
Color outerColor = new Color(25, 25, 0);
Color[] colors = {centerColor , outerColor };
RadialGradientPaint paint = new RadialGradientPaint(center, radius, dist, colors);
Graphics2D g2 = img.createGraphics();
g2.setPaint(paint);
g2.fillRect(0, 0, img.getWidth(), img.getHeight());
g2.dispose();
return img;
}
private static void createAndShowGui() {
FrameEg mainPanel = new FrameEg();
JFrame frame = new JFrame("FrameEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class MyPanel extends JPanel {
private Dimension prefSize;
private BufferedImage backgroundImg;
public MyPanel(Dimension prefSize) {
this.prefSize = prefSize;
}
public void setBackgroundImg(BufferedImage background) {
this.backgroundImg = background;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImg != null) {
g.drawImage(backgroundImg, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
return prefSize;
}
}
#SuppressWarnings("serial")
class MyBorder extends AbstractBorder {
private BufferedImage borderImg;
private Insets insets;
public MyBorder(BufferedImage borderImg, Insets insets) {
this.borderImg = borderImg;
this.insets = insets;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
g.drawImage(borderImg, 0, 0, c);
}
#Override
public Insets getBorderInsets(Component c) {
return insets;
}
}
Which would look like:
My code has a JPanel that contains three collapsible JPanels. The outer JPanel uses the BoxLayout to stack the three JPanels vertically. However, when I collapse a JPanel, the top JPanel will always expands to fill the region (even if I setMaximumSize() or such), whereas I want the lower JPanels to expand upward. It is generally glitchy. I was looking at the GridBagLayout, would that be more suitable for this sort of endeavor?
Thanks.
This is a VB image of what I dream about in my wildest dreams (images with title "Vertical Panels"):
http://www.codeproject.com/KB/cpp/CollapsiblePanelVB.aspx
I don't know what a collapsable panel is. Does it collapse all the way to 0, or does is have a minimum height?
If you manage the maximum size to always equal the preferred size then you should be able to use a BoxLayout. Just make sure you also use:
panel.add( Box.createVerticalGlue() );
at the bottom of your panel to allow the extra space to be used by the glue.
It would take me forever to cut out a compilable snippet from the 500 lines of garbage sprawled out before me.
And that is the reason for creating a SSCCE and forgetting about your garbage code. All you need is a panel with 3 collapsable panels. Then you add a button to collapse the panel and see what happens. Its better to start with demo code then write 500 lines of code and find out it doesn't work.
I strongly suggest MigLayout. It's very powerful and very easy to use. It's also widely used.
or old classic based on GridBagLayout
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class ExpansiblePanel {
public static void main(String[] args) {
CollapsablePanel cp = new CollapsablePanel("test", buildPanel());
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(cp));
f.setPreferredSize(new Dimension(360, 200));
f.setLocation(150, 150);
f.pack();
f.setVisible(true);
}
public static JPanel buildPanel() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 1, 2, 1);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
JPanel p1 = new JPanel(new GridBagLayout());
gbc.gridwidth = GridBagConstraints.RELATIVE;
p1.add(new JButton("button 1"), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
p1.add(new JButton("button 2"), gbc);
gbc.gridwidth = GridBagConstraints.RELATIVE;
p1.add(new JButton("button 3"), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
p1.add(new JButton("button 4"), gbc);
p1.setBackground(Color.blue);
return p1;
}
private ExpansiblePanel() {
}
}
class CollapsablePanel extends JPanel {
private static final long serialVersionUID = 1L;
private boolean selected;
private JPanel contentPanel_;
private HeaderPanel headerPanel_;
private class HeaderPanel extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
private String text_;
private Font font;
private BufferedImage open, closed;
final int OFFSET = 30, PAD = 5;
HeaderPanel(String text) {
addMouseListener(this);
text_ = text;
font = new Font("sans-serif", Font.PLAIN + Font.BOLD, 12);
// setRequestFocusEnabled(true);
setPreferredSize(new Dimension(200, 25));
setBackground(Color.black);
setForeground(Color.red);
int w = getWidth();
int h = getHeight();
/*try {
open = ImageIO.read(new File("images/arrow_down_mini.png"));
closed = ImageIO.read(new File("images/arrow_right_mini.png"));
} catch (IOException e) {
e.printStackTrace();
}*/
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int h = getHeight();
/*if (selected)
g2.drawImage(open, PAD, 0, h, h, this);
else
g2.drawImage(closed, PAD, 0, h, h, this);
*/ // Uncomment once you have your own images
g2.setFont(font);
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = font.getLineMetrics(text_, frc);
float height = lm.getAscent() + lm.getDescent();
float x = OFFSET;
float y = (h + height) / 2 - lm.getDescent();
g2.drawString(text_, x, y);
}
#Override
public void mouseClicked(MouseEvent e) {
toggleSelection();
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
}
CollapsablePanel(String text, JPanel panel) {
super(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(1, 3, 0, 3);
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
selected = false;
headerPanel_ = new HeaderPanel(text);
setBackground(Color.orange);
contentPanel_ = panel;
add(headerPanel_, gbc);
add(contentPanel_, gbc);
contentPanel_.setVisible(false);
JLabel padding = new JLabel();
gbc.weighty = 1.0;
add(padding, gbc);
}
public void toggleSelection() {
selected = !selected;
if (contentPanel_.isShowing()) {
contentPanel_.setVisible(false);
} else {
contentPanel_.setVisible(true);
}
revalidate();
headerPanel_.repaint();
}
}