The code below is taken from:
How to always show vertical scroll bar in SWT table?
Table in the ScrolledComposite scrolls only by moving vertical scrollbar by Mouse or by putting Mouse directly onto vertical scrollbar and scroll the Wheel.
Could you advise, please, how to make table scrollable by Mouse Wheel by putting Mouse onto the Table?
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final ScrolledComposite composite = new ScrolledComposite(shell, SWT.V_SCROLL);
composite.setLayout(new GridLayout());
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Table table = new Table(composite, SWT.NO_SCROLL | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
composite.setContent(table);
composite.setExpandHorizontal(true);
composite.setExpandVertical(true);
composite.setAlwaysShowScrollBars(true);
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Button fillTable = new Button(shell, SWT.PUSH);
fillTable.setText("Fill table");
fillTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
fillTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
if (table.getColumnCount() < 1)
{
for (int col = 0; col < 4; col++)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Column " + col);
}
}
for (int row = 0; row < 20; row++)
{
TableItem item = new TableItem(table, SWT.NONE);
for (int col = 0; col < table.getColumnCount(); col++)
{
item.setText(col, "Item " + row + " " + col);
}
}
for (int col = 0; col < table.getColumnCount(); col++)
{
table.getColumn(col).pack();
}
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
Button clearTable = new Button(shell, SWT.PUSH);
clearTable.setText("Clear table");
clearTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
clearTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
table.removeAll();
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
shell.pack();
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
The table is receiving the mouse wheel events which it is ignoring because the Table control is large enough to show all the rows.
I don't see a way to just pass on the wheel events to the scrolled composite.
You could try listening to the wheel events in the table and adjusting the scrolled composite origin - something like:
table.addListener(SWT.MouseVerticalWheel, event ->
{
Point origin = scrolled.getOrigin();
origin.y -= event.count;
scrolled.setOrigin(origin);
});
The count field in the wheel event is 1/-1 depending on the scrolling direction.
Related
I took the attached code from How to always show vertical scroll bar in SWT table?, except for the nuber of rows being 4000 instead of 20. In that case I can not go beyond 1416 rows in the table, what is the reason for that ?
private static final int MAX_ROWS = 4000;
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final ScrolledComposite composite = new ScrolledComposite(shell, SWT.V_SCROLL);
composite.setLayout(new GridLayout());
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Table table = new Table(composite, SWT.NO_SCROLL | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
composite.setContent(table);
composite.setExpandHorizontal(true);
composite.setExpandVertical(true);
composite.setAlwaysShowScrollBars(true);
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Button fillTable = new Button(shell, SWT.PUSH);
fillTable.setText("Fill table");
fillTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
fillTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
if (table.getColumnCount() < 1)
{
for (int col = 0; col < 4; col++)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Column " + col);
}
}
for (int row = 0; row < MAX_ROWS; row++)
{
TableItem item = new TableItem(table, SWT.NONE);
for (int col = 0; col < table.getColumnCount(); col++)
{
item.setText(col, "Item " + row + " " + col);
}
}
for (int col = 0; col < table.getColumnCount(); col++)
{
table.getColumn(col).pack();
}
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
Button clearTable = new Button(shell, SWT.PUSH);
clearTable.setText("Clear table");
clearTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
clearTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
table.removeAll();
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
shell.pack();
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
In the following code, I give 2000 labels inside the ScrolledComposite. But I see only 1400+ labels. I find that this is due to OS restriction. I need the workaround for this with canvas.
Display display = new Display();
Shell parent = new Shell(display);
parent.setLayout(new GridLayout(1, false));
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
final ScrolledComposite scrolledComposite = new ScrolledComposite(parent,
SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setExpandVertical(true);
final Composite childComposite = new Composite(scrolledComposite, SWT.NONE);
scrolledComposite.setContent(childComposite);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
childComposite.setLayout(layout);
for (int i = 0; i < 2000; i++) {
Label label = new Label(childComposite, SWT.BORDER);
label.setText("Label " + i);
}
Point size = childComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
scrolledComposite.setMinSize(size);
parent.setSize(parent.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, 200);
parent.open();
while (!parent.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();`
I am new be in RCP development.
I want to create two tables with, each table contains different data.
Data from two tables have either 1 to 1 , 1 to many or many to 1 relationship.
And that can be done by drawing arrows between two tables.
For example,
**Row 1** **Row 2**
R1 V1 R2 V1
R1 V2 R2 V2
R1 V3 R2 V3
I want to draw arrows from R1V1 to ( R2V1 and R2V3 ) or vice a versa.
How can I show it graphically.
How can I find that which rows are combined by arrows.
Any help is appreciated.
--- Mandar
Here is the code that is based on the idea proposed by Nick. It is just to give an idea for someone who might wonder where to start to implement something like this shown below
This would let you click on any column on the left hand side table, then draws a line as your mouse moves on towards the right table, and anchors the line as soon as a column on the right hand side table is selected. It keeps a mapping between the left table row and right table row in a linked list as the mapping data model.
package sample;
import java.util.LinkedList;
import org.eclipse.draw2d.AutomaticRouter;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FreeformLayeredPane;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.draw2d.XYAnchor;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class GraphicTableMapper {
private static Point sourcePosition;
private static PathFigure currentPath;
private static Figure bf;
private static Canvas canvas;
private static int sourceRow;
private static int targetRow;
private static LinkedList<RowMapper> rowmapList = new LinkedList<RowMapper>();
public static void main(String[] args) {
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setSize(550, 500);
shell.setLayout(new GridLayout(3, false));
final Table table = new Table(shell, SWT.MULTI | SWT.BORDER
| SWT.FULL_SELECTION);
table.setLinesVisible(true);
table.setHeaderVisible(true);
final String[] titles = { "Serial Number", "Whatever" };
for (int i = 0; i < titles.length; i++) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText(titles[i]);
}
int count = 100;// create 100 rows in table
for (int i = 0; i < count; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, "x");
item.setText(1, "y");
item.setText(2, "!");
item.setText(3, "this stuff behaves the way I expect");
item.setText(4, "almost everywhere");
item.setText(5, "some.folder");
item.setText(6, "line " + i + " in nowhere");
}
for (int i = 0; i < titles.length; i++) {
table.getColumn(i).pack();
}
table.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
Point pt = new Point(event.x, event.y);
TableItem item = table.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
int index = table.indexOf(item);
System.out.println("Item " + index + "-" + i);
sourcePosition = pt;
sourceRow = index;
currentPath = new PathFigure();
currentPath.setSourceAnchor(new XYAnchor(
new org.eclipse.draw2d.geometry.Point(-10,
event.y)));
currentPath
.setTargetAnchor(new XYAnchor(
new org.eclipse.draw2d.geometry.Point(
0, pt.y)));
bf.add(currentPath);
}
}
}
});
table.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent arg0) {
if (currentPath != null) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
0, arg0.y));
}
}
});
canvas = new Canvas(shell, SWT.None);
canvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_GREEN));
LightweightSystem lws = new LightweightSystem(canvas);
bf = new BaseFigure();
lws.setContents(bf);
canvas.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent arg0) {
if (currentPath != null) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
arg0.x > canvas.getSize().x - 5 ? canvas
.getSize().x - 5 : arg0.x, arg0.y));
}
}
});
GridData data2 = new GridData();
data2.verticalAlignment = SWT.TOP;
data2.grabExcessHorizontalSpace = false;
data2.grabExcessVerticalSpace = true;
data2.horizontalIndent = -10;
data2.widthHint = 200;
data2.heightHint = 1000;
canvas.setLayoutData(data2);
final Table table2 = new Table(shell, SWT.MULTI | SWT.BORDER
| SWT.FULL_SELECTION);
table2.setLinesVisible(true);
table2.setHeaderVisible(true);
data2 = new GridData();
data2.grabExcessHorizontalSpace = false;
data2.horizontalIndent = -10;
table2.setLayoutData(data2);
final String[] titles2 = { "Serial Number", "Whatever" };
for (int i = 0; i < titles.length; i++) {
TableColumn column = new TableColumn(table2, SWT.NONE);
column.setText(titles[i]);
canvas.redraw();
}
table2.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent event) {
if (currentPath != null) {
Point pt = new Point(event.x, event.y);
TableItem item = table2.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles2.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
canvas.getSize().x - 5, event.y));
}
}
}
}
});
int count2 = 100;// create 100 rows in table 2
for (int i = 0; i < count2; i++) {
TableItem item = new TableItem(table2, SWT.NONE);
item.setText(0, "x");
item.setText(1, "y");
item.setText(2, "!");
item.setText(3, "this stuff behaves the way I expect");
item.setText(4, "almost everywhere");
item.setText(5, "some.folder");
item.setText(6, "line " + i + " in nowhere");
}
for (int i = 0; i < titles.length; i++) {
table2.getColumn(i).pack();
}
table2.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
try {
Point pt = new Point(event.x, event.y);
TableItem item = table2.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles2.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
int index = table2.indexOf(item);
targetRow = index;
System.out.println("Item " + index + "-" + i);
if (sourcePosition != null) {
add(event);
}
}
}
} finally {
sourcePosition = null;
sourceRow = -1;
targetRow = -1;
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public static void add(Event event) {
bf.remove(currentPath);
PathFigure figure = new PathFigure();
figure.setSourceAnchor(currentPath.getSourceAnchor());
figure.setTargetAnchor(currentPath.getTargetAnchor());
bf.add(figure);
currentPath = null;
RowMapper mapper = new RowMapper();
mapper.sourceRow = sourceRow;
mapper.targetRow = targetRow;
if (!rowmapList.contains(mapper)) {
rowmapList.add(mapper);
}
}
class BaseFigure extends FreeformLayeredPane {
public BaseFigure() {
setLayoutManager(new FreeformLayout());
setBorder(new MarginBorder(5));
setBackgroundColor(ColorConstants.white);
setOpaque(true);
}
}
class PathFigure extends PolylineConnection {
public PathFigure() {
setTargetDecoration(new PolylineDecoration());
setConnectionRouter(new AutomaticRouter() {
#Override
protected void handleCollision(PointList list, int index) {
}
});
}
}
class RowMapper {
int sourceRow;
int targetRow;
#Override
public boolean equals(Object obj) {
if (obj instanceof RowMapper) {
RowMapper mapper = (RowMapper) obj;
return (sourceRow == mapper.sourceRow && targetRow == mapper.targetRow);
}
return false;
}
}
This is quite a difficult component to implement, I did one of these for Tibco Business Studio some time ago.
You'll need to place a Canvas between your two tables to draw the links on. You presumably have data models for your two tables, you'll also need a third model for storing the links and ensure that any modifications to this model trigger a refresh of the Canvas.
Next add drag and drop support to the two tables, dropping an item from table 1 onto table 2 should create a new item in your link model (thus triggering a Canvas refresh to draw the link).
Actually drawing the links in the right locations you'll have to work out yourself, but hopefully this gives you some ideas to start with.
Am I right in thinking that this implementation uses the mouse location to draw the arrows? So if you wanted to save / load a relationship you would have to save the x,y positions of the arrows and you'd have to make sure your components always stayed the same size?
Ok. so I'm writing a grocery checkout system code and on the right side of the frame, I'm displaying a Jpanel with Labels. Every time I click the 'Scan' button, I add a new label into the JPanel so that everytime I click, it displays the output. However, I can only fit so many entries in my window, how do I incorporate a scroll bar so that I can scroll through the groceries?
I tried inputting a scroll bar EAST with a BorderLayout and all the labels CENTER, however, everytime I click the button, it only reprints it at the same exact spot instead of top/down so that I can scroll. (Please, bare in mind that this is a very very rough draft. I'll be incorporating the logic beneath the code once I get the nitty-gritty with the GUI)
Here's my code:
public class Checkout extends JFrame implements ActionListener
{
private int numOfItems = 21;
private Integer[] itemCode = new Integer[numOfItems];
private StringBuffer[] itemDesc = new StringBuffer[numOfItems];
private Double[] unitPrice = new Double[numOfItems];
private Integer[] taxCode = new Integer[numOfItems];
private Integer[] quantity = new Integer[numOfItems];
private Integer[] reorderLevel = new Integer[numOfItems];
private double subTotal, tax, grandTotal;
private JButton scan = new JButton("Scan");
private JButton pay = new JButton("Finish & Pay");
private JButton readFile = new JButton("Read from File");
private JTextField itemNumber = new JTextField(4);
private JTextField itemQuantity = new JTextField(4);
private JLabel displayReceipt = new JLabel();
private JPanel p4;
public Checkout()
{
setValues();
JPanel p2 = new JPanel(new FlowLayout());
p2.add(scan);
p2.add(pay);
p2.add(readFile);
JPanel p1 = new JPanel(new FlowLayout());
p1.add(new JLabel("Item Number:"));
p1.add(itemNumber);
p1.add(new JLabel("Item Quantity:"));
p1.add(itemQuantity);
p1.setBorder(new TitledBorder("Scan Items First. Then Hit 'Finish and Pay'"));
JPanel p3 = new JPanel(new BorderLayout(5, 5));
p3.add(p1, BorderLayout.NORTH);
p3.add(p2, BorderLayout.CENTER);
p4 = new JPanel(new GridLayout(0, 1, 0, 0));
JScrollPane scroll = new JScrollPane(p4);
add(p3, BorderLayout.WEST);
add(p4, BorderLayout.CENTER);
scan.addActionListener(this);
pay.addActionListener(this);
readFile.addActionListener(this);
}
public void setValues()
{
String[] tokens = new String[6];
String[][] multi = new String[numOfItems][6];
try{BufferedReader textReader = new BufferedReader(new FileReader("inventory.txt"));
for(int i = 0; i < numOfItems; i++) // Split the file
{
tokens = textReader.readLine().split("\t");
for(int j = 0; j < tokens.length; j++)
{
multi[i][j] = tokens[j];
}
}
for(int i = 0; i < numOfItems; i++)
{
itemCode[i] = (Integer.parseInt(multi[i][0]));
itemDesc[i] = new StringBuffer(multi[i][1]);
unitPrice[i] = (Double.parseDouble(multi[i][2]));
taxCode[i] = (Integer.parseInt(multi[i][3]));
quantity[i] = (Integer.parseInt(multi[i][4]));
reorderLevel[i] = (Integer.parseInt(multi[i][5]));
}}
catch(Exception e){}
}
public void setQuantity(int item, int itemCount)
{
for(int i = 0; i < numOfItems; i++)
{
if(itemCode[i].equals(item))
{
quantity[i] = quantity[i] - itemCount;
subTotal = itemCount * unitPrice[i];
if(quantity[i] < reorderLevel[i])
itemDesc[i] = itemDesc[i].append("**MARKED FOR REORDER**\t");
}
}
}
public String toString()
{
System.out.println("CUST TICKET");
//for(int i = 0; i < numOfItems; i++)
//return (itemCode[i] + "\t" + itemDesc[i] + "\t" + unitPrice[i] + "\t" + taxCode[i] + "\t" + quantity[i] + "\t" + reorderLevel[i]);
System.out.println("SUBTOTAL\t" + subTotal);
System.out.println("TAX\t\t" + tax);
System.out.println("GRAND TOTAL\t" + grandTotal);
return "";
}
public static void main(String[] args) throws Exception
{
Checkout frame = new Checkout(); // Frame layout
frame.setSize(600, 135);
frame.setTitle("Computer Science 202: Final Project - Supermarket Checkout System");
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
/*Scanner input = new Scanner(System.in);
System.out.print("Please enter item number: ");
Integer itemNumber = Integer.parseInt(input.nextLine());
System.out.print("Please enter quantity: ");
Integer quantity = Integer.parseInt(input.nextLine());
System.out.println(frame.stockCheck(itemNumber, quantity));*/
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == scan)
{
try
{
Integer quantityOrdered = 1;
Integer item = Integer.parseInt(itemNumber.getText());
quantityOrdered = Integer.parseInt(itemQuantity.getText());
for(int i = 0; i < numOfItems; i++)
{
if(itemCode[i].equals(item))
{
if(quantityOrdered > 1)
{
p4.add(new JLabel(itemDesc[i] + "" + unitPrice[i]));
p4.add(new JLabel(quantityOrdered + " # " + unitPrice[i]));
p4.revalidate();
p4.repaint();
}
else
{
p4.add(new JLabel(itemDesc[i] + "\t" + unitPrice[i]));
p4.revalidate();
p4.repaint();
}
}
}
setQuantity(item, quantityOrdered);
}
catch(Exception ex){}
}
else if(e.getSource() == pay)
{
displayReceipt.setText(toString());
}
else if(e.getSource() == readFile)
{
System.out.println("READ FILE");
}
}
}
How can I insert a SWT Button control into JFace TableViewer ?
The answer given is nice a nice way to implement your own buttons with custom drawings, in or outside the a table. However, you can put SWT controls in JFace Tables.
http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/PlacearbitrarycontrolsinaSWTtable.htm
The solution for building a table with columns containing comboboxes, text fields, and buttons provided by the link is:
Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
table.setLinesVisible(true);
for (int i = 0; i < 3; i++) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setWidth(100);
}
for (int i = 0; i < 12; i++) {
new TableItem(table, SWT.NONE);
}
TableItem[] items = table.getItems();
for (int i = 0; i < items.length; i++) {
TableEditor editor = new TableEditor(table);
CCombo combo = new CCombo(table, SWT.NONE);
editor.grabHorizontal = true;
editor.setEditor(combo, items[i], 0);
editor = new TableEditor(table);
Text text = new Text(table, SWT.NONE);
editor.grabHorizontal = true;
editor.setEditor(text, items[i], 1);
editor = new TableEditor(table);
Button button = new Button(table, SWT.CHECK);
button.pack();
editor.minimumWidth = button.getSize().x;
editor.horizontalAlignment = SWT.LEFT;
editor.setEditor(button, items[i], 2);
}
You can't. More generally, you can't insert any widgets in tables and trees in SWT, because not all platforms support it. What you can do instead is
Take two screenshots of the button in normal and clicked states;
Put the normal screenshot in table as an image;
Handle clicks on the TableItem.
Here is an example for checkboxes: http://tom-eclipse-dev.blogspot.com/2007/01/tableviewers-and-nativelooking.html