I have one "main" panel. I'd like to have a "side" panel inside the main one. The side is composed of two other panels, let's call one graphicPanel and one supportPanel. I'm trying to add labels to the SupportPanel from the main one, but no changes happen.
Here is my side panel:
public class LateralSupportPane extends JPanel{
private final static int WIDTH = 240;
private final static int HEIGHT = 740;
private GraphicPanel gp;
private SupportPanel sp;
public LateralSupportPane(){
this.gp = new GraphicPanel();
this.sp = new SupportPanel();
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setLayout(new GridLayout(2, 1));
//this.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(gp);
this.add(sp);
this.setVisible(true);
}
public void addLabel(String label){
sp.addLabel(label);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
gp.paintComponent(g);
}
public void addLabel(String label){
sp.addLabel(label);
}
Here my supportPanel:
public class SupportPanel extends JPanel{
private JLabel label;
private final static int WIDTH = 240;
private final static int HEIGHT = 370;
public SupportPanel(){
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
label = new JLabel();
label.setText("<html>BlaBla</html>");
this.setLayout(new GridLayout(10, 1));
this.add(label);
this.setVisible(true);
}
public JLabel getLabel() {
return label;
}
public void addLabel(String text){
JLabel label = new JLabel(text);
if(this.getComponentCount() < 10){
this.add(label);
} else {
this.remove(0);
this.add(label);
}
}
From the main panel I call the addLabel of the side panel.
EDIT: Here is the frame with all panels. The board itself is a panel added into a frame. The board also has another panel, that are the black rectangle and the area where the string is, together. Then the side panel is composed by 2 other panels, the GraphicPanel (the black rectangle) and the supportPanel, that is the area where I'd like to have my labels.
Board
Validating all panels made no progress.
Not sure if i undurstend it correctly, but it seams, that you have to validate your panels after inserting new label;
public static void main(String[] args) {
JFrame frame = new JFrame("test");
frame.setSize(900, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new CardLayout());
frame.setVisible(true);
LateralSupportPane p = new LateralSupportPane();
frame.add(p);
frame.validate();
p.addLabel("test 2");
p.validate();
}
as you see, after adding a label, validation is performed and object is painted on form.
your method addLabel(String label) should have this method called at end of it.
Related
I've made a HallOfFame class which is subclass of JPanel and i want to add a label writing "Hall OF Fame" on this panel.In the MainWindow class (frame) i have added the HallOfFame (Panel) to the content pane but nothing shows up. The same happens with every component i am trying to add on the frame (MainWindow) except the top (placed North with the BorderLayout) panel with 3 buttons.
public class HallOfFame extends JPanel{
JLabel hofLabel;
public HallOfFame() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setBorder(new LineBorder(Color.GRAY, 1));
this.setAlignmentX(CENTER_ALIGNMENT);
hofLabel = new JLabel("Hall OF Fame");
add(hofLabel);
}
}
public class MainWindow extends JFrame{
/*Size of main window*/
public static final Dimension winSize = new Dimension(1200, 800);
public static final int TOP_HEIGHT = 80;
public static final int PLAYER_WIDTH = 300;
private GameBoard gameBoard;
private HallOfFame hallOfFame;
private BannerPanel bannerPanel;
private PlayerPanel playerPanel;
public MainWindow() {
//Initializing the frame.
Container c = this.getContentPane();
c.setPreferredSize(winSize);
this.setTitle("TucTacToe");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*Hall of fame*/
hallOfFame = new HallOfFame();
/*GameBoard*/
gameBoard = new GameBoard();
/*Banner Panel*/
bannerPanel = new BannerPanel();
/*PlayerPanel*/
playerPanel = new PlayerPanel();
/*Adding the components to the window*/
c.add(bannerPanel, BorderLayout.NORTH);
c.add(hallOfFame, BorderLayout.CENTER);
//add(gameBoard, BorderLayout.CENTER);
c.add(playerPanel);
this.pack();
this.setVisible(true);//setting visible the frame.
}
}
Here is the window of the project
c.add(hallOfFame, BorderLayout.CENTER);
c.add(playerPanel)
You are adding the "playerPanel" to the CENTER of the frame. When you don't specify the constraint it defaults to the CENTER when using BorderLayout.
Only the last component added will be visible. So it appears your playerPanel doesn't have any components added to it.
For a simple test just use:
c.add(hallOfFame, BorderLayout.CENTER);
//c.add(playerPanel)
Now you should see the hallOfFame panel.
I'm trying to add a small tornado graphic (upside down pyramid) to my Frame. I can get the tornado by adding it to the frame in the main method but when I do that all I see is the tornado graphic and not the GUI underneath it.
So, I'm now trying to add the Tornado graphic to the frame when its created in the createComponents method but it now doesn't appear at all. Instead all I can see it the GUI in the frame.
I' probably missing something easy but I can't seem to figure it out. I'm not sure what I need to to in order to get the GUI and the tornado graphic both to appear.
public class EFScaleViewer {
public static void main(String[] args) {
// TODO Auto-generated method stub
TornadoFrame frame = new TornadoFrame();
frame.setTitle("EF Scale");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here is where I create the frame and am trying to add the tornado:
public class TornadoFrame extends JFrame{
private JButton submit;
private JLabel label;
static JLabel errorLabel;
static JTextField textBox;
JPanel tornado = new TornadoComponent();
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 300;
//Constructor for the frame
public TornadoFrame() {
super();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
createComponents();
}
private void createComponents()
{
textBox = new JTextField(" ");
submit = new JButton("Submit");
label = new JLabel("Please enter a windspeed:");
errorLabel = new JLabel("Error Message " );
JPanel panel = new JPanel();
panel.add(label);
panel.add(textBox);
panel.add(submit);
panel.add(errorLabel);
panel.add(tornado);
add(panel);
}
}
I know this is working but I may be missing something so here is where I create the tornado:
public class TornadoComponent extends JPanel {
public void paintComponent(Graphics g) {
int[] xPoints = {100,200,0};
int[] yPoints = {0,200,200};
int nPoints = 3;
g.drawPolygon(xPoints, yPoints, nPoints);
}
}
You have to set the JPanels size for it to be able to display Graphics.
static class TornadoComponent extends JPanel {
public TornadoComponent() {
setPreferredSize(new Dimension(500, 500));
}
#Override
public void paintComponent(Graphics g) {
//Whatever
}
}
And in order to trigger paintComponent(Graphics g) you have to add tornado.repaint(); at the end of your createComponents() function.
private void createComponents() {
//All your components
panel.add(tornado);
add(panel);
tornado.repaint();
}
Now the Polygon is shown but not at the right place (slightly off the image)
Therefore we have to arrange your JPanels a bit:
private void createComponents() {
textBox = new JTextField(" ");
submit = new JButton("Submit");
label = new JLabel("Please enter a windspeed:");
errorLabel = new JLabel("Error Message " );
JPanel upper = new JPanel();
upper.setLayout(new BoxLayout(upper,BoxLayout.X_AXIS));
upper.add(label);
upper.add(textBox);
upper.add(submit);
upper.add(errorLabel);
JPanel lower = new JPanel();
lower.setLayout(new BoxLayout(lower,BoxLayout.X_AXIS));
lower.add(tornado);
JPanel over = new JPanel();
over.setLayout(new BoxLayout(over,BoxLayout.Y_AXIS));
over.add(upper);
over.add(lower);
add(over);
tornado.repaint();
}
Basically I make some boxes...
Over
Upper
... your stuff with text
Lower
Our tornado
Now our tornado is the wrong way round...
int[] xPoints = {100,200,150};
int[] yPoints = {0,0,150};
And voilĂ :
We just created a very basic tornado that is not aiming at anything :)
If you want to change the tornados position later you just have to recall tornado.repaint(); and you are all set.
I am trying to create a board class that extends JPanel for a backgammon game and a JLayeredPane to create a dragging area for my checkers but i cant even print a simple rectangle to the panel. It does print the image but not the JLabel.
Here is my JPanel class
public class BoardPanel extends JPanel{
private JLayeredPane lp;
private BufferedImage imageBoard;
private final int WIDTH = 1000;
private final int HEIGHT = 800;
private ArrayList<Slot> slotSet1;
private ArrayList<Slot> slotSet2;
private ArrayList<Slot> slotSet3;
private ArrayList<Slot> slotSet4;
private CheckerSet ch1;
public Checker chc;
public BoardPanel(){
initComponents();
}
private void initComponents(){
lp = new JLayeredPane();
setPreferredSize(new java.awt.Dimension(1500, 1000));
//lp.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
lp.setBorder(javax.swing.BorderFactory.createTitledBorder("asdadsaddadsadasdadsa"));
lp.setMaximumSize(new java.awt.Dimension(1124, 904));
lp.setMinimumSize(new java.awt.Dimension(1124, 904));
try {
imageBoard = ImageIO.read(getClass().getResource("/images/board.jpg"));
} catch (IOException e) {
System.out.println("file error");
}
JLabel label = new JLabel();
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.BLACK);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setBounds(0, 0, 50, 50);
lp.add(label,JLayeredPane.DEFAULT_LAYER);
}
public void paintComponent(Graphics g){
//g.drawImage(imageBoard,0,0,null);
}
}
And there is the main
public static void main(String[] args){
JFrame f = new JFrame();
//GamePanel gp = new GamePanel();
BoardPanel gp = new BoardPanel();
f.add(gp);
//f.getContentPane().add(gamePanel);
f.setSize(new Dimension(1500, 1000));
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
How can i resolve it? Thanks guys
You will have to add a Layout to your JLayeredPane, like a GridLayout for example. Try this:
GridLayout gl = new GridLayout(20, 21);
lp.setLayout(gl);
after initializing lp. Then you can add all components that you Need to the GridLayout, for instance lp:
gl.add(lp)
The Layout will manage how the things will be displayed; in this case, it will fill the grid from the GridLayout, first the first row (of which 20 exist), then the second one and so on (I don't think you actually Need 20 rows, it is just like that in my example code)
I have a desktop application in swing. I have a JPanel in which the image as the background and in it two buttons and a JScrollPane as shown in the picture Frame with JPanel. I have a function (showLabel()) which, when JScrollPane the end, add JLabel with transparent images and disappear a few seconds. The problem is that when you add JLabel. JLabel bad shows as seen in Fig Bad shows. Can you help me with my problem?
public class MainWindow {
private JFrame frame;
private PanelPopis panelPopis = new PanelPopis(this);
private MyPaint myPaint;
public MainWindow {
setWindow():
BufferedImage image1 = ImageIO.read(getClass().getClassLoader().getResource("poz.png"));
this.myPaint = new MyPaint(image1);
this.frame.add(myPaint);
this.myPaint.add(panelPopis.setPanel());
}
private void setWindow() {
this.frame = new JFrame("DD");
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.setSize(400, 680);
this.frame.setResizable(false);
this.frame.setLocationRelativeTo(null);
}
private void showLabel(){
JLabel label = new JLabel();
label.setIcon(new ImageIcon(new ImageIcon(getClass().getClassLoader().getResource("postEn.png")).getImage().getScaledInstance(395, 653, Image.SCALE_DEFAULT)));
label.setBackground(new Color(0, 0, 0, 10));
label.setOpaque(true);
this.frame.invalidate();
this.frame.add(label);
this.frame.revalidate();
int delay2 = 3000; // milliseconds
ActionListener taskPerformer2 = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
frame.remove(label);
frame.revalidate();
frame.repaint();
}
};
Timer myTimer2 = new Timer(delay2, taskPerformer2);
myTimer2.setRepeats(false);
myTimer2.start();
}
}
public class MyPaint extends JPanel {
private static final long serialVersionUID = 1L;
BufferedImage image;
public MyPaint(BufferedImage image) {
setOpaque(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 395, 653, this);
}
}
public class PanelPopis extends JPanel {
private static final long serialVersionUID = 7676683627217636485L;
private JButton setLanguage;
private JButton cont;
private JScrollPane scrolPanel;
private JTextArea popis;
private MainWindow mainWindow;
public PanelPopis(MainWindow mainWindow) {
this.mainWindow = mainWindow;
}
public JPanel setPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setOpaque(false);
JPanel panel2 = new JPanel();
Border border = panel2.getBorder();
Border margin = new EmptyBorder(0, 0, 4, 0);
panel2.setBorder(new CompoundBorder(border, margin));
panel2.setOpaque(false);
panel2.add(this.scrolPanel = new JScrollPane(popis));
panel.add(this.setLanguage = new JButton("language settings"), BorderLayout.NORTH);
panel.add(this.cont = new JButton("CONTINUE"), BorderLayout.SOUTH);
panel.add(panel2, BorderLayout.CENTER);
return panel;
}
}
I would suggest to use the getResource() method instead of the getResourceAsStream() and have the path of both images inputted there this way.
The classLoader could behave differently (in your case due to the differences between the two OS's) so doing it this way would guarantee that you application is always getting the correct resources.
More on the getResource here:
https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
public class InputPanel extends JPanel{
public static int shapeType; //1: Rectangle; 2: Oval; 3: Line
public static boolean isFilled; //whether or not the shape is filled
public static Color color; //color of the shape
public InputPanel(){
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.setBackground(Color.GRAY);
setPreferredSize(new Dimension(200,500));
JButton rect = new JButton("Rectangle");
JButton oval = new JButton("Oval");
JButton line = new JButton("Line");
JRadioButton fill = new JRadioButton("Filled:");
JButton color1 = new JButton("Color..");
rect.addActionListener(new rectListener());
oval.addActionListener(new ovalListener());
line.addActionListener(new lineListener());
isFilled = fill.isSelected();
color1.addActionListener(new colorListener());
panel.add(rect);
panel.add(oval);
panel.add(line);
panel.add(fill);
panel.add(color1);
this.setVisible(true);
}
}
public class PaintPanel extends JPanel{
public static int x1, y1, x2, y2;
ArrayList<Shape> shapeList = new ArrayList<Shape>();
public PaintPanel(){
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
panel.setBackground(Color.WHITE);
setPreferredSize(new Dimension(500, 500));
this.addMouseListener(new MouseAdapter() {
#Override public void mousePressed(MouseEvent e) {
PaintPanel.x1 = e.getX();
PaintPanel.y1 = e.getY();
}
#Override public void mouseReleased(MouseEvent e) {
PaintPanel.x2 = e.getX();
PaintPanel.y2 = e.getY();
if(InputPanel.shapeType == 1){
shapeList.add(new Rectangle(PaintPanel.x1, PaintPanel.y1, PaintPanel.x2, PaintPanel.y2, InputPanel.isFilled));
}
if(InputPanel.shapeType == 2){
shapeList.add(new Oval(PaintPanel.x1, PaintPanel.y1, PaintPanel.x2, PaintPanel.y2, InputPanel.isFilled));
}
if(InputPanel.shapeType == 3){
shapeList.add(new Line(PaintPanel.x1, PaintPanel.y1, PaintPanel.x2, PaintPanel.y2));
}
repaint();
}
});
this.setVisible(true);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
for(Shape s : shapeList){
s.draw(g);
}
}
}
public class PaintGUI {
public static void main(String[] args){
JFrame frame = new JFrame("Shape Drawer!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new InputPanel());
frame.add(new PaintPanel());
frame.pack();
frame.setVisible(true);
}
}
I'm positive I've created the JFrame properly and all of my other classes work, but there must be something in here I'm missing...
When I run the main method all I get is a gray box that is clearly a square (500x500, as instantiated in the PaintPanel class. What am I doing wrong?
Apart from what Andrew mentioned, I noticed that within both your InputPanel and PaintPanel you're creating a new JPanel. You're adding new components to this panel, for sure, but at the end you're not adding this JPanel itself to your InputPanel or PaintPanel. So, make sure that in your constructors for these panels you have a add(panel) at the end.
Also, as a side note, do please keep in mind that most operations in Swing are not thread-safe and so read about "Concurrency in Swing" before creating/interacting with UI components. In other words, any updates to the user interface must happen on the event dispatch thread, like the start-up of your application:
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Shape Drawer!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//set the layout, add your panels
frame.pack();
frame.setVisible(true);
}
});
}
JFrame by default uses BorderLayout.
frame.add(new InputPanel());
frame.add(new PaintPanel());
is equivalent to saying,
frame.add(new InputPanel(), BorderLayout.CENTER);
frame.add(new PaintPanel(), BorderLayout.CENTER);
The net result being that the Panel that is added last would be the one that is visible, provided the rest of your code is working correctly.
Must add the panel to the frame, use:
this.add(panel);