# 3
Erh... I don't really need coding help... It's more like a design advice, like what layout I should use... But since you asked, here it is
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.Box;
import javax.swing.BoxLayout;
public class DepthForm
{
private static final int MAX_LINE = Share.MAX_DEPTH_LINE;
private static Dimension pSize = new Dimension(100,90);
private JFrame frame = new JFrame();
private JLabel[] bidLev = new JLabel[MAX_LINE];
private JLabel[] bidVol = new JLabel[MAX_LINE];
private JLabel[] askLev = new JLabel[MAX_LINE];
private JLabel[] askVol = new JLabel[MAX_LINE];
private Border leftBorder;
private Border rightBorder;
private JPanel leftPane = new JPanel();
private JPanel rightPane = new JPanel();
public DepthForm()
{
JPanel mainPane = new JPanel();
leftBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
rightBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
leftPane.setLayout(new GridLayout(MAX_LINE,3));
leftPane.setBorder(BorderFactory.createTitledBorder(leftBorder, "Bid", TitledBorder.LEFT, TitledBorder.TOP));
rightPane.setLayout(new GridLayout(MAX_LINE,3));
rightPane.setBorder(BorderFactory.createTitledBorder(rightBorder,"Offer", TitledBorder.LEFT, TitledBorder.TOP));
for (int i = 0; i < MAX_LINE; i++)
{
bidLev[i] = new JLabel("<html><font color=blue></font></html>", JLabel.LEFT);
bidVol[i] = new JLabel("", JLabel.RIGHT);
askLev[i] = new JLabel("<html><font color=red></font></html>", JLabel.LEFT);
askVol[i] = new JLabel("", JLabel.RIGHT);
}
for (int i = 0; i < MAX_LINE; i++)
{
JLabel l = new JLabel(" ");
leftPane.add(bidLev[i]);
leftPane.add(l);
leftPane.add(bidVol[i]);
rightPane.add(askLev[i]);
l = new JLabel(" ");
rightPane.add(l);
rightPane.add(askVol[i]);
}
leftPane.setMinimumSize(pSize);
leftPane.setMaximumSize(pSize);
leftPane.setPreferredSize(pSize);
rightPane.setMinimumSize(pSize);
rightPane.setMaximumSize(pSize);
rightPane.setPreferredSize(pSize);
mainPane.add(leftPane);
mainPane.add(rightPane);
frame.setContentPane(mainPane);
frame.setVisible(false);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
public void setBidLevLabel(int i, String s)
{
bidLev[i].setText("<html><font color=blue>" + s + "</font></html>");
}
public void setBidVolLabel(int i, String s)
{
bidVol[i].setText(s);
}
public void setAskLevLabel(int i, String s)
{
askLev[i].setText("<html><font color=red>" + s + "</font></html>");
}
public void setAskVolLabel(int i, String s)
{
askVol[i].setText(s);
}
public void setFrameTitle(String s)
{
frame.setTitle(s);
}
public void showDepth()
{
frame.setVisible(true);
}
public void hideDepth()
{
frame.setVisible(false);
}
}
Also, another design question, if I need to display something similar, but instead of only 5 rows, it can be up to 1500 lines (enclosed in a JScrollPane of course), what should I use? JTextArea is good, but it can't color certain part of text... JEditorPane can color text, but I can't append text at the first line... :(
# 5
Oh well, for the purpose of learning. Please put the code in a file called Test.java
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.Box;
import javax.swing.BoxLayout;
public class Test
{
//private static final int MAX_LINE = Share.MAX_DEPTH_LINE;
private static final int MAX_LINE = 5;
private static Dimension pSize = new Dimension(100,90);
private JFrame frame = new JFrame();
private JLabel[] bidLev = new JLabel[MAX_LINE];
private JLabel[] bidVol = new JLabel[MAX_LINE];
private JLabel[] askLev = new JLabel[MAX_LINE];
private JLabel[] askVol = new JLabel[MAX_LINE];
private Border leftBorder;
private Border rightBorder;
private JPanel leftPane = new JPanel();
private JPanel rightPane = new JPanel();
public Test()
{
JPanel mainPane = new JPanel();
leftBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
rightBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
leftPane.setLayout(new GridLayout(MAX_LINE,3));
leftPane.setBorder(BorderFactory.createTitledBorder(leftBorder, "Bid", TitledBorder.LEFT, TitledBorder.TOP));
rightPane.setLayout(new GridLayout(MAX_LINE,3));
rightPane.setBorder(BorderFactory.createTitledBorder(rightBorder,"Offer", TitledBorder.LEFT, TitledBorder.TOP));
for (int i = 0; i < MAX_LINE; i++)
{
bidLev[i] = new JLabel("<html><font color=blue></font></html>", JLabel.LEFT);
bidVol[i] = new JLabel("", JLabel.RIGHT);
askLev[i] = new JLabel("<html><font color=red></font></html>", JLabel.LEFT);
askVol[i] = new JLabel("", JLabel.RIGHT);
}
for (int i = 0; i < MAX_LINE; i++)
{
JLabel l = new JLabel(" ");
leftPane.add(bidLev[i]);
leftPane.add(l);
leftPane.add(bidVol[i]);
rightPane.add(askLev[i]);
l = new JLabel(" ");
rightPane.add(l);
rightPane.add(askVol[i]);
}
leftPane.setMinimumSize(pSize);
leftPane.setMaximumSize(pSize);
leftPane.setPreferredSize(pSize);
rightPane.setMinimumSize(pSize);
rightPane.setMaximumSize(pSize);
rightPane.setPreferredSize(pSize);
mainPane.add(leftPane);
mainPane.add(rightPane);
frame.setContentPane(mainPane);
frame.setVisible(false);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
public void setBidLevLabel(int i, String s)
{
bidLev[i].setText("<html><font color=blue>" + s + "</font></html>");
}
public void setBidVolLabel(int i, String s)
{
bidVol[i].setText(s);
}
public void setAskLevLabel(int i, String s)
{
askLev[i].setText("<html><font color=red>" + s + "</font></html>");
}
public void setAskVolLabel(int i, String s)
{
askVol[i].setText(s);
}
public void setFrameTitle(String s)
{
frame.setTitle(s);
}
public void showTest()
{
frame.setVisible(true);
}
public void hideTest()
{
frame.setVisible(false);
}
public static void main(String[] args)
{
Test d = new Test();
d.showTest();
d.setBidLevLabel(0,"111111");
d.setBidLevLabel(1,"222222");
d.setBidLevLabel(2,"333333");
d.setBidLevLabel(3,"444444");
d.setBidLevLabel(4,"55555");
d.setBidVolLabel(0,"1111");
d.setBidVolLabel(1,"2222");
d.setBidVolLabel(2,"3333");
d.setBidVolLabel(3,"4444");
d.setBidVolLabel(4,"5555");
d.setAskLevLabel(0,"111111");
d.setAskLevLabel(1,"222222");
d.setAskLevLabel(2,"333333");
d.setAskLevLabel(3,"444444");
d.setAskLevLabel(4,"55555");
d.setAskVolLabel(0,"1111");
d.setAskVolLabel(1,"2222");
d.setAskVolLabel(2,"3333");
d.setAskVolLabel(3,"4444");
d.setAskVolLabel(4,"5555");
}
}
As you can see, each panel is divided into 3 even columns... And texts in 1st column are missing. If I widen the column widths (by increase the panel size), the middle column will become even bigger. I want the middle column (the gap) to be smaller while the other column widths are unchanged.... Which layout should I use to achieve that?
# 9
[nobr]Here's my humble invention called TableLayout. Usage in your case is as follows:container.setLayout(new TableLayout(new int[] {3, 2}, 10, 0));
This will define a table with 2 columns with 10 pixels between them. The relative cell widths 3 and 2 will automatically stretch to fill the container's size. (I noticed the columns in your little text art drawing are 6 and 4 characters wide)
Here's the class:package digisoft.custom.swing;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.io.Serializable;
import java.util.Arrays;
/**
* A Layout Manager which creates a basic table of components. The widths of the
* cells are specified as a ratio array of <code>int</code>. The relative
* widths of the rendered columns will always follow these ratios.<br>
*
* The preferred widths of the columns will be either the sum of the columns
* with configured widths as pixels, or the configured ratios stretched equally
* in such a way that no single component is narrower than it's own preferred
* width, whichever is larger, added to the sum of the gap widths. When the
* width of the parent container is larger, the cells are simply stretched
* linearly according to the configured ratios.
*
* A special case is when a ratio is specified as zero. In these cases, each
* column specified as zero will get such a preferred width that no single
* component inside that column is narrower than it's own preferred width. These
* columns do stretch, however, when the width of the parent container is larger
* than the preferred width, everything is stretched linearly.
*
* For example, a <code>TableLayout</code> with column widths
* <code>{5, 2}</code> filled with equal components with a width of 100 pixels
* will generate a layout with preferred column widths of 250 and 100 pixels
* (ratio 5:2). Setting this layout to a container with an absolute width of 700
* pixels will force the table columns to 500 and 200 pixels wide.<br>
*
* Another example. A <code>TableLayout</code> with column widths
* <code>{0, 200, 0, 120}</code> filled with different components for each
* column with relative widths of 30, 100, 50 and 100 pixels will generate a
* layout with preferred column widths of 30, 200, 50 and 120 pixels (ratio
* x:200:x:120). Setting this layout to a container with an absolute width of
* 800 pixels will force the table columns to 60, 400, 100 and 240 pixels wide.
*
* @author Mark Jeronimus
* @since 1.0
* @see LayoutManager
* @see Component#getPreferredSize()
*
* date 2006/11/24
*/
public class TableLayout implements LayoutManager, Serializable
{
private inthgap;
private intvgap;
private int[]columns;
private int[]colWidths;
private intnumColumns;
private int[]rowHeights;
private intlayoutWidthTotal;
private intwidestColumn;
/**
* Create an empty TableLayout. Call <code>setColumns</code> to start
* using it.
*
* @since 1.0
*/
public TableLayout()
{
this(new int[]{0}, 0, 0);
}
/**
* Create a TableLayout with specified column width ratios.
*
* @param columns
*the column width ratios
* @throws IllegalArgumentException
* when the array is null, the array length is zero or one of
* the array elements is negative
* @since 1.0
*/
public TableLayout(int[] columns)
{
this(columns, 0, 0);
}
/**
* Create a TableLayout with specified column width ratios and gap sizes.
*
* @param columns
*the column width ratios
* @param hgap
*the horizontal space between all columns, in pixels
* @param vgap
*the vertical space between all rows, in pixels
* @throws IllegalArgumentException
* when the array is null, the array length is zero or one of
* the array elements is negative
* @since 1.0
*/
public TableLayout(int[] columns, int hgap, int vgap)
{
this.setColumns(columns);
this.setHgap(hgap);
this.setVgap(vgap);
}
/**
* Set or change the column width ratios.
*
* @param columns
*the column width ratios
* @throws IllegalArgumentException
* when the array is null, the array length is zero or one of
* the array elements is negative
* @since 1.0
*/
public void setColumns(int[] columns)
{
if (columns == null || columns.length == 0)
{
throw new IllegalArgumentException("No columns specified");
}
this.columns = columns;
this.numColumns = this.columns.length;
int widestColumnSize = -1;
this.widestColumn = 0;
for (int i = 0; i < this.numColumns; i++)
{
int w = this.columns[i];
if (w < 0)
{
throw new IllegalArgumentException("Negative column width specified at index " + i);
}
this.layoutWidthTotal += w;
if (w > 0 && widestColumnSize < w)
{
widestColumnSize = w;
this.widestColumn = i;
}
}
this.colWidths = new int[this.columns.length];
}
/**
* Returns the column width ratios. The returned array is a direct reference
* to the contained column array, so care must be taken not to alter any
* elements to illegal values (negative values).
*
* @return the column width ratios
* @since 1.0
*/
public int[] getColumnns()
{
return this.columns;
}
/**
* Set or change the horizontal space between all columns, in pixels
*
* @param hgap
*the horizontal space between all columns, in pixels
* @since 1.0
*/
public void setHgap(int hgap)
{
if (hgap < 0)
{
throw new IllegalArgumentException("Negative hgap specified");
}
this.hgap = hgap;
}
/**
* Get the horizontal space between all columns, in pixels
*
* @return the horizontal space between all columns, in pixels
* @since 1.0
*/
public int getHgap()
{
return this.hgap;
}
/**
* Set or change the vertical space between all rows, in pixels
*
* @param vgap
*the vertical space between all rows, in pixels
* @since 1.0
*/
public void setVgap(int vgap)
{
if (vgap < 0)
{
throw new IllegalArgumentException("Negative vgap specified");
}
this.vgap = vgap;
}
/**
* Get the vertical space between all rows, in pixels
*
* @return the vertical space between all rows, in pixels
* @since 1.0
*/
public int getVgap()
{
return this.vgap;
}
/**
* {@inheritDoc}
*/
@Override
public void addLayoutComponent(String name, Component comp)
{
}
/**
* {@inheritDoc}
*/
@Override
public void removeLayoutComponent(Component comp)
{
}
/**
* {@inheritDoc}
*/
@Override
public Dimension preferredLayoutSize(Container parent)
{
synchronized (parent.getTreeLock())
{
Insets insets = parent.getInsets();
int components = parent.getComponentCount();
int numRows = (components + this.numColumns - 1) / this.numColumns;
this.rowHeights = new int[numRows];
Arrays.fill(this.rowHeights, 0);
int narrowestColumn = this.widestColumn;
int narrowestSize = this.columns[this.widestColumn];
int component = 0;
for (int y = 0; y < numRows; y++)
{
for (int x = 0; x < this.numColumns; x++)
{
Component comp = parent.getComponent(component++);
Dimension d = comp.getPreferredSize();
if (this.columns[x] == 0)
{
if (this.colWidths[x] < d.width)
{
this.colWidths[x] = d.width;
}
}
else if (d.width > this.columns[x] * narrowestSize / this.columns[narrowestColumn])
{
if (this.columns[x] > 0)
{
narrowestColumn = x;
}
narrowestSize = d.width;
}
if (this.rowHeights[y] < d.height)
{
this.rowHeights[y] = d.height;
}
if (component == components)
{
break;
}
}
}
int totalWidth = insets.left + insets.right + (this.numColumns - 1) * this.hgap;
for (int x = 0; x < this.numColumns; x++)
{
if (this.columns[x] != 0)
{
this.colWidths[x] = this.columns[x] * narrowestSize / this.columns[narrowestColumn];
}
totalWidth += this.colWidths[x];
}
int totalHeight = insets.top + insets.bottom + (numRows - 1) * this.vgap;
for (int y = 0; y < numRows; y++)
{
totalHeight += this.rowHeights[y];
}
return new Dimension(totalWidth, totalHeight);
}
}
/**
* {@inheritDoc}
*/
@Override
public Dimension minimumLayoutSize(Container parent)
{
synchronized (parent.getTreeLock())
{
Insets insets = parent.getInsets();
int components = parent.getComponentCount();
int numRows = (components + this.numColumns - 1) / this.numColumns;
int[] colWidths = new int[this.numColumns];
System.arraycopy(this.columns, 0, colWidths, 0, this.numColumns);
int[] rowHeights = new int[numRows];
Arrays.fill(rowHeights, 0);
int component = 0;
for (int y = 0; y < numRows; y++)
{
for (int x = 0; x < this.numColumns; x++)
{
Component comp = parent.getComponent(component++);
Dimension d = comp.getMinimumSize();
if (colWidths[x] < d.width)
{
colWidths[x] = d.width;
}
if (rowHeights[y] < d.height)
{
rowHeights[y] = d.height;
}
if (component == components)
{
break;
}
}
}
int totalWidth = insets.left + insets.right + (this.numColumns - 1) * this.hgap;
for (int x = 0; x < this.numColumns; x++)
{
totalWidth += colWidths[x];
}
int totalHeight = insets.top + insets.bottom + (numRows - 1) * this.vgap;
for (int y = 0; y < numRows; y++)
{
totalHeight += rowHeights[y];
}
return new Dimension(totalWidth, totalHeight);
}
}
/**
* {@inheritDoc}
*/
@Override
public void layoutContainer(Container parent)
{
synchronized (parent.getTreeLock())
{
Insets insets = parent.getInsets();
int components = parent.getComponentCount();
int numRows = (components + this.numColumns - 1) / this.numColumns;
Dimension preferredSize = this.preferredLayoutSize(parent);
int width = parent.getWidth() - (insets.left + insets.right + (this.numColumns - 1) * this.hgap);
int height = parent.getHeight() - (insets.top + insets.bottom + (numRows - 1) * this.vgap);
int preferredWidth = preferredSize.width - (insets.left + insets.right + (this.numColumns - 1) * this.hgap);
int preferredHeight = preferredSize.height - (insets.top + insets.bottom + (numRows - 1) * this.vgap);
int[] currentColWidths = new int[this.numColumns];
for (int x = 0; x < this.numColumns; x++)
{
currentColWidths[x] = this.colWidths[x] * width / preferredWidth;
}
int[] currentRowHeights = new int[numRows];
for (int y = 0; y < numRows; y++)
{
currentRowHeights[y] = this.rowHeights[y] * height / preferredHeight;
}
int component = 0;
int yPos = insets.top;
for (int y = 0; y < numRows; y++)
{
int xPos = insets.left;
for (int x = 0; x < this.numColumns; x++)
{
parent.getComponent(component++).setBounds(xPos, yPos, currentColWidths[x], currentRowHeights[y]);
if (component == components)
{
break;
}
xPos += currentColWidths[x] + this.hgap;
}
yPos += currentRowHeights[y] + this.vgap;
}
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return super.getClass().getSimpleName() + "[columns=" + this.columns + ", hgap=" + this.hgap + ", vgap=" + this.vgap + "]";
}
}
[/nobr]
Zom-Ba at 2007-7-12 18:12:29 >
