cjard, the tutorial is excellent, thanks for taking the time to put it together. That goes for the jar tutorial as well. BIG help.
The following code is for an app I'm doing for school. It creates a GUI layout that is supposed to resemble a craps table and except for the finishing touches it does. There is however one problem I cannot get rid of. When I run it the bottom of the window shows some dead space I don't want to be seen. This is probably because I didn't do it right in the first place and if I am unable to fix this I will live with it. If anyone can tell me how to correct this I'd be deeply appreciative. You will probably have to copy/paste and run it to see what I mean. It won't compile if you don't have the die images so I commented out all that stuff already.
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CrapsTable2 extends JFrame{
public static void addComponentsToPane(Container pane) {
GridBagConstraints c = new GridBagConstraints();
GridBagConstraints p = new GridBagConstraints();
ImageIcon die1, die2, die3, die4, die5, die6, die7, die8;
JLabel[] topLabels = new JLabel[7];
JLabel[] upperPlaceBetsLabels = new JLabel[6];
JLabel[] lowerPlaceBetsLabels = new JLabel[6];
JButton bigSixEightButton, bottomButton;
JButton[] topButtons = new JButton[3];
JButton[] lowerPassBars = new JButton[2];
JButton[] numberBetsButtons = new JButton[6];
JButton[] hardWays = new JButton[4];
JButton[] [] hardWayBets = new JButton[2] [2], oneRollBets = new JButton[2] [2];
JButton fieldButton, comeButton;
JPanel hardWayBetsPanel, oneRollBetsPanel, comeFieldPanel;
JLabel comeLabel,bottomLabel,bottomLabel2, lowestLabel;
Color green = new Color(15, 160, 30);
//die1 = new ImageIcon("images\\die1.png");
//die2 = new ImageIcon("images\\die2.png");
//die3 = new ImageIcon("images\\die3.png");
//die4 = new ImageIcon("images\\die4.png");
//die5 = new ImageIcon("images\\die5.png");
//die6 = new ImageIcon("images\\die6.png");
//die7 = new ImageIcon("images\\die7.png");
//die8 = new ImageIcon("images\\die8.png");
Dimension firstTopLabelDim, topLabelsDim, comeBarDim, passLinesDim, placeBetsDim,
numberBetsButtonsDim, hardWaysDim, hardWayBetsPanelDim, oneRollBetsPanelDim,
comeButtonDim, fieldButtonDim,comeFieldPanelDim, bigSixEightLabelDim,
bigSixEightLabelDim2, lowerPassBarsDim, bottomButtonDim;
Insets noInset = new Insets(0,0,0,0), hardWaysInset = new Insets(8,8,0,8),hardWaysBetsInset
= new Insets(0,8,0,8), fieldButtonInset = new Insets(87,0,0,75),
oneRollBetsInset = new Insets(4,8,0,8),bigSixEightInset = new Insets
(87,450,143,50), comeButtonInset = new Insets(0,0,0,10), dontPassInset = new
Insets(0,0,69,0), lowerPassBarsInset =new Insets(21,0,143,75),
lowerPassBarsInset2 = new Insets(38, 0, 130, 0), dontPassInset2 = new Insets
(0,0,143,0), bottomLabelInset = new Insets(0,0,12,0), bottomLabel2Inset = new
Insets(0,20,12,0), bottomButtonInset = new Insets (63,21,75,1);
pane.setLayout(new GridBagLayout());
pane.setBackground(green);
c.fill = GridBagConstraints.BOTH;
for(int i = 0; i < topLabels.length; i++){
c.gridx = i * 10;
c.gridy = 10;
c.gridheight = 10;
topLabels[i] = new JLabel("", 0);
if(i < 1){
firstTopLabelDim = new Dimension(190, 200);
topLabels[i].setPreferredSize(firstTopLabelDim);
topLabels[i].setText("<html><font size=7 color=lime>CASINO<br>CRAPS<br><br><font size=3>Minimum Bet: $1<br>MaximumBet: $10<font></html>");
c.gridheight = 40;
}
else{
topLabelsDim = new Dimension(85,50);
topLabels[i].setPreferredSize(topLabelsDim);
c.anchor = GridBagConstraints.NORTH;
}
if(i > 0){
topLabels[i].setBorder(BorderFactory.createLineBorder(Color.white));
}
topLabels[i].setBackground(green);
pane.add(topLabels[i], c);
}
for(int i = 0; i < topButtons.length; i++){
topButtons[i] = new JButton();
c.gridx = (i + 7) * 10;
c.gridy = 10;
c.gridheight = 40;
c.insets = noInset;
if(i < 1){
comeBarDim = new Dimension(100, 200);
topButtons[i].setPreferredSize(comeBarDim);
}
else{
c.gridheight = 100;
passLinesDim = new Dimension(50, 300);
topButtons[i].setPreferredSize(passLinesDim);
c.insets = dontPassInset2;
}
if(i == 1){
c.gridheight = 60;
c.insets = dontPassInset;
}
topButtons[i].setBorder(BorderFactory.createLineBorder(Color.white));
pane.add(topButtons[i], c);
}
topButtons[0].setText("<html><font size=2 color=black>D<br>O<br>N<br>T<br><br>C<br>O<br>M<br>E<br><br>B<br>A<br>R<font</html>");
topButtons[1].setText("<html><font size=2 color=black>D<br>O<br>N<br>T<br><br>P<br>A<br>S<br>S<br><br>B<br>A<br>R<font</html>");
topButtons[2].setText("<html><font size=2 color=black>P<br>A<br>S<br>S<br><br>L<br>I<br>N<br>E<font</html>");
topButtons[0].setBackground(green);
topButtons[1].setBackground(green);
topButtons[2].setBackground(green);
c.insets = noInset;
for(int i = 0; i < upperPlaceBetsLabels.length; i++){
c.gridx = (i + 1) * 10;
c.gridy = 20;
c.gridheight = 10;
upperPlaceBetsLabels[i] = new JLabel("<html><font size=2 color=red>PLACE BETS<font></html>", 0);
placeBetsDim = new Dimension(85, 25);
upperPlaceBetsLabels[i].setPreferredSize(placeBetsDim);
upperPlaceBetsLabels[i].setBorder(BorderFactory.createLineBorder(Color.white));
upperPlaceBetsLabels[i].setBackground(green);
pane.add(upperPlaceBetsLabels[i], c);
}
for(int i = 0; i < numberBetsButtons.length; i++){
c.gridx = (i + 1) * 10;
c.gridy = 30;
c.gridheight = 10;
numberBetsButtons[i] = new JButton();
numberBetsButtonsDim = new Dimension(85, 100);
numberBetsButtons[i].setPreferredSize(numberBetsButtonsDim);
numberBetsButtons[i].setBackground(green);
numberBetsButtons[i].setBorder(BorderFactory.createLineBorder(Color.white));
if(i == 0){
numberBetsButtons[i].setText("<html><font size=8 color=yellow>4<font></html>");
}
else if(i == 1){
numberBetsButtons[i].setText("<html><font size=8 color=yellow>5<font></html>");
}
else if(i == 2){
numberBetsButtons[i].setText("<html><font size=6 color=yellow>SIX<font></html>");
}
else if(i == 3){
numberBetsButtons[i].setText("<html><font size=8 color=yellow>8<font></html>");
}
else if(i == 4){
numberBetsButtons[i].setText("<html><font size=6 color=yellow>NINE<font></html>");
}
else{
numberBetsButtons[i].setText("<html><font size=8 color=yellow>10<font></html>");
}
pane.add(numberBetsButtons[i], c);
}
holy smokes! this thing goes bananas when it's resized! 1024x768 only eh? you might do better to make your JFRame non-resizable after it has been pack()ed.. that will kill the deadspace at the bottom too
In fact.. if you wrote this in NetBeans, it would be great to ahve the project form files.. I think your large deadspace problem at the bottom is caused by being a little overzealous with the insets
I fixed the indents, thx for the tip.
This project is not due for three weeks so I am going to redo the GUI right. This is my new start and if you run it you will see I am having problems with two of the labels and I don't see why. The casino craps label isn't taking on the dimension it should and I have a stragler on the top row furthest east who isn't behaving either. I can't understand why this is the case. Also, what's up with the sun java site? I haven't been able to get in all day, am I the only one?
Code:
import java.awt.event.*;
import javax.swing.*;
public class CrapsTable3 extends JFrame{
public static void addComponentsToPane(Container pane){
GridBagConstraints c = new GridBagConstraints();
JButton[] buttonArray = new JButton[30];
int indxB = 0;
JLabel[] labelArray = new JLabel[25];
int indxL = 0;
Dimension casinoLabelDim, placeBetsLabelDim, placeBetsButtonDim;
pane.setLayout(new GridBagLayout());
for(int i = 0; i < buttonArray.length; i++){
buttonArray[i] = new JButton();
buttonArray[i].setBorder(BorderFactory.createLineBorder(Color.white));
}
for(int i = 0; i < labelArray.length; i++){
labelArray[i] = new JLabel();
labelArray[i].setBorder(BorderFactory.createLineBorder(Color.white));
}
//sets the casino craps label
c.gridx = 10;
c.gridy = 10;
c.gridheight = 40;
c.fill = GridBagConstraints.VERTICAL;
casinoLabelDim = new Dimension (300, 500);
labelArray[indxL].setMinimumSize(casinoLabelDim);
indxL++;
pane.add(labelArray[indxL], c);
//sets labels for the number bets grid
c.gridheight = 1;
c.fill = GridBagConstraints.NONE;
for(int i = 1; i <= 19; i++){
c.gridx = (i + 1) * 10;
c.gridy = 10;
placeBetsLabelDim = new Dimension (85, 40);
if(i > 6){
c.gridx = ((i + 1) * 10) - 60;
c.gridy = 20;
placeBetsLabelDim = new Dimension (85, 30);
}
if(i > 12){
c.gridx = ((i + 1) * 10) - 120;
c.gridy = 40;
}
labelArray[indxL].setPreferredSize(placeBetsLabelDim);
indxL++;
pane.add(labelArray[indxL], c);
}
//sets number bets buttons
for(int i = 1; i <= 7; i++){
c.gridx = (i + 1) * 10;
c.gridy = 30;
placeBetsButtonDim = new Dimension (85, 80);
buttonArray[indxB].setPreferredSize(placeBetsButtonDim);
indxB++;
pane.add(buttonArray[indxB], c);
}
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I've been tooling around with it and it seems like it matters in what order things are done. If I add a component and in the next line set its dimensions it doesn't show up. I don't know. I still can't get the cottonpicking thing to work right.
cjard, why can't I get the fieldPanel to work? I tried doing with a gridbag layout and everything stayed crushed in the middle no matter what I did. I tried flow layout but I won't be able to get what I want unless I can figure out how to do it with gridbag.
Originally posted by beamo
I redid the GUI and it is much more manageable now but I don't understand why the label backrounds aren't being set while the buttons are.
probably because labels are transparent by default; setOpaque(false),
but buttons are solid by default; setOpaque(true)
int[][] buttonData = new int[][]{new int[]{5,3,3,3, 3, 3, 3},
new int[]{2,3,4,9,10,11,12}};
int x=10, y=10;
for(int i = 0; i < 6; i++){
c.gridx = x;
c.gridy = y;
c.weightx = 1.0;
c.gridwidth = 10;
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
buttonArray[indxB].setText("<html><font size=" + buttonData[0][i] +
" color=yellow>"+buttonData[1][i] +
"<font></html");
dimension = new Dimension(57, 40);
buttonArray[indxB].setPreferredSize(dimension);
fieldPanel.add(buttonArray[indxB], c);
indxB++;
x+=10;
}
your buttons were collapsing because you had never given them a size they could obey - you set the preferred size to 57x40, but it was not achievable in one or more dimensions because the panel is only 400 wide, 84 high, it has a border, and apparently, some implicit insets - each button has a border, and somewhere along the line, you lost sufficient number of pixels such that 6 buttons were either wider than 400, or higher than 84 (when combined with any other elements)
the size they were adopting was the implicit minimum one thanks to the text they had to contain..
also, i note that you have never given components a weight.. it is perhaps the most important part of gridbag, as it defines how components will resize.. In fact, maybe i should have pointed out in the tut, that preferred sizes should only really be set for components whose weightX/Y is 0.0; for all other components, the layout manager should be allowed to set the preferred size, based on the weights
Of course, all components need a minimum size so that graceful collapse may occur. For many components the default minimum size is acceptable (based on content) but for specially laid out interfaces like yours, minimum size should be enforced, to mainatin a graceful ui
i'll recap some things:
min size: the minimum size a component can be, to effectively perform its job
preferred size: the min size a component should be, in order to look nice
weightx/y: how components will succeed in the fight for extra space that is made available
to un-collapse your buttons, i simply gave them all a weight of 1.0 - they will fight for space now, within the panel, and end up where each has an equal amount of space
remember: weight determines the size of the grid cell, and FILL determines how the component will look inside its cell. fill will not cause a component to fill extra space (expand its cell) - it merely causes it to grow until it reaches the bounds of its cell
you will need to have a further look at your minimum and preferred sizes - well, the preferreds are okay, but the display goes mental if resized to smaller then preferred.. the minimum sizes of most components are such that they are very tall and thin, shoving most components off screen
additionally, you need to decide which components should resize and by how much, when new space comes available. if the fieldPanel get 66% of any new space, and the remaining 3 component on the line fight over the 33%, then make the weightxs 6, 1,1,1 respectively
dontforget the weightys
Last edited by cjard; March 8th, 2004 at 06:55 AM.
I ended up getting by without the panel, though I may go back and try it out anyway, I've been learning a lot this way. I've attached the project folder so you can see how it looks now. I have to go back and clean up the code a little along the lines that you showed me above. If you have any suggestions please feel free. THANKS.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.