| /******************************************************************************* |
| * Copyright (c) 2018 Red Hat and others. All rights reserved. |
| * The contents of this file are made available under the terms |
| * of the GNU Lesser General Public License (LGPL) Version 2.1 that |
| * accompanies this distribution (lgpl-v21.txt). The LGPL is also |
| * available at http://www.gnu.org/licenses/lgpl.html. If the version |
| * of the LGPL at http://www.gnu.org is different to the version of |
| * the LGPL accompanying this distribution and there is any conflict |
| * between the two license versions, the terms of the LGPL accompanying |
| * this distribution shall govern. |
| * |
| * Contributors: |
| * Red Hat - initial API and implementation |
| */ |
| package org.eclipse.swt.tests.manualJUnit; |
| |
| import java.text.Collator; |
| import java.util.Arrays; |
| import java.util.Locale; |
| import java.util.Random; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| import java.util.function.BiConsumer; |
| import java.util.function.BiFunction; |
| import java.util.function.Consumer; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.TableEditor; |
| import org.eclipse.swt.events.ControlAdapter; |
| import org.eclipse.swt.events.ControlEvent; |
| import org.eclipse.swt.events.ControlListener; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.events.ShellAdapter; |
| import org.eclipse.swt.events.ShellEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontMetrics; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.graphics.TextLayout; |
| import org.eclipse.swt.graphics.TextStyle; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.layout.RowData; |
| import org.eclipse.swt.layout.RowLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.ScrollBar; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.swt.widgets.Text; |
| import org.junit.FixMethodOrder; |
| import org.junit.Test; |
| import org.junit.runners.MethodSorters; |
| |
| @FixMethodOrder(MethodSorters.NAME_ASCENDING) // To make it easier for human to go through the tests. Same order makes tests easier to recognize. |
| public class MJ_Table extends MJ_root { |
| |
| // Shared elements: |
| final Listener ownerDrawnListener = event -> { |
| final TableItem item = (TableItem)event.item; |
| Table table = item.getParent(); |
| AtomicBoolean packpending = (AtomicBoolean) table.getData(); |
| |
| if (event.type == SWT.EraseItem) { |
| } |
| |
| if (event.type == SWT.PaintItem) { |
| final String text1 = (String)item.getData() + " (gc)"; |
| if (event.index == 0) { |
| event.gc.drawText(text1, event.x, event.y, true); |
| } |
| } |
| if (event.type == SWT.MeasureItem) { |
| event.height = 50; |
| event.width = 100; |
| } |
| if (event.type == SWT.SetData) { |
| final int index = table.indexOf(item); |
| final String data = "Virtual item:" + index; |
| item.setData(data); |
| item.setText("VirtItem " + index); |
| if (table.getColumnCount() > 1) { |
| for (int i = 1; i <= table.getColumnCount(); i++) { |
| item.setText(i, " Col: " + i + " " + data); |
| } |
| } |
| |
| if (packpending.get()) { |
| packpending.set(false); |
| display.asyncExec(() -> { |
| table.setRedraw(false); |
| for (TableColumn column : table.getColumns()) { |
| column.pack(); |
| } |
| table.setRedraw(true); |
| }); |
| } |
| } |
| }; |
| |
| /** |
| * <a href="https://bugs.eclipse.org/bugs/attachment.cgi?id=272647">Screenshot </a> |
| */ |
| @Test |
| public void ownerDrawn_cheese_single_col () { |
| knownToBeBrokenGtk3("Cheese on gtk3"); // z for warning |
| Shell shell = mkShell("Expected: There should be no cheese in the items. Move over shouldn't cheese out. See javadoc for screenshot"); |
| shell.setLayout(new FillLayout(SWT.VERTICAL)); |
| |
| final Table table = new Table(shell, SWT.VIRTUAL | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); |
| |
| AtomicBoolean packpending = new AtomicBoolean(true); |
| table.setData(packpending); |
| |
| table.addListener(SWT.EraseItem, ownerDrawnListener); // Not relevant. |
| table.addListener(SWT.SetData, ownerDrawnListener); |
| table.addListener(SWT.MeasureItem, ownerDrawnListener); |
| table.addListener(SWT.PaintItem, ownerDrawnListener); |
| |
| final TableColumn tableColumn = new TableColumn(table, SWT.LEFT); |
| tableColumn.setText("First Left Column"); |
| tableColumn.setMoveable(true); |
| |
| table.setItemCount(100); |
| |
| shell.setSize(800, 600); // Shell size seems to have a little bit of an initial impact. (may show proper with some shell sizes, incorrectly for others). |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void ownerDrawn_cheese_multiple_col() { |
| final Shell shell = mkShell("Expected: No cheese in multiple column, also mouse move over no cheese."); |
| shell.setLayout(new FillLayout(SWT.VERTICAL)); |
| final Table table = new Table(shell, SWT.VIRTUAL | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); |
| |
| AtomicBoolean packpending = new AtomicBoolean(true); |
| table.setData(packpending); |
| |
| table.addListener(SWT.EraseItem, ownerDrawnListener); |
| table.addListener(SWT.SetData, ownerDrawnListener); |
| table.addListener(SWT.MeasureItem, ownerDrawnListener); |
| table.addListener(SWT.PaintItem, ownerDrawnListener); |
| |
| BiConsumer<Integer, String> createColCons = (colStyle, colName) -> { |
| final TableColumn tableColumn = new TableColumn(table, colStyle); |
| tableColumn.setText(colName); |
| tableColumn.setMoveable(true); |
| }; |
| |
| createColCons.accept(SWT.LEFT, "LEFT"); |
| createColCons.accept(SWT.CENTER, "CENTER"); |
| createColCons.accept(SWT.RIGHT, "RIGHT"); |
| |
| int ItemCount = 1000; |
| table.setItemCount(ItemCount); |
| table.setHeaderVisible(true); |
| |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| /** |
| * <a href="http://www.eclipse.org/articles/Article-CustomDrawingTableAndTreeItems/customDraw.htm#_example4"> Screenshot </a> |
| */ |
| @Test |
| public void ownerDrawn_eraseItem_Snippet273() { |
| knownToBeBrokenGtk3("Test currently broken on Gtk3. See Comment#1 of Bug 531551"); |
| |
| final String[] MONTHS = { |
| "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
| "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
| }; |
| final int[] HIGHS = {-7, -4, 1, 11, 18, 24, 26, 25, 20, 13, 5, -4}; |
| final int[] LOWS = {-15, -13, -7, 1, 7, 13, 15, 14, 10, 4, -2, -11}; |
| final int SCALE_MIN = -30; final int SCALE_MAX = 30; |
| final int SCALE_RANGE = Math.abs(SCALE_MIN - SCALE_MAX); |
| |
| Shell shell = mkShell(" Gtk3:broken, no erasing (1st March 2018) Gtk2: Background is used as bar-chart of sort. See screenshot."); |
| final Color blue = display.getSystemColor(SWT.COLOR_BLUE); |
| final Color white = display.getSystemColor(SWT.COLOR_WHITE); |
| final Color red = display.getSystemColor(SWT.COLOR_RED); |
| // final Image parliamentImage = new Image(display, "./parliament.jpg"); |
| final Table table = new Table(shell, SWT.NONE); |
| table.setBounds(10,10,350,300); |
| // table.setBackgroundImage(parliamentImage); |
| for (int i = 0; i < 12; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(MONTHS[i] + " (" + LOWS[i] + "C..." + HIGHS[i] + "C)"); |
| } |
| final int clientWidth = table.getClientArea().width; |
| |
| /* |
| * NOTE: MeasureItem and EraseItem are called repeatedly. Therefore it is |
| * critical for performance that these methods be as efficient as possible. |
| */ |
| table.addListener(SWT.MeasureItem, event -> { |
| int itemIndex = table.indexOf((TableItem)event.item); |
| int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE; |
| event.width = rightX; |
| }); |
| table.addListener(SWT.EraseItem, event -> { |
| int itemIndex = table.indexOf((TableItem)event.item); |
| int leftX = (LOWS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE; |
| int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE; |
| GC gc = event.gc; |
| Rectangle clipping = gc.getClipping(); |
| clipping.x = leftX; |
| clipping.width = rightX - leftX; |
| gc.setClipping(clipping); |
| Color oldForeground = gc.getForeground(); |
| Color oldBackground = gc.getBackground(); |
| gc.setForeground(blue); |
| gc.setBackground(white); |
| gc.fillGradientRectangle(event.x, event.y, event.width / 2, event.height, false); |
| gc.setForeground(white); |
| gc.setBackground(red); |
| gc.fillGradientRectangle( |
| event.x + event.width / 2, event.y, event.width / 2, event.height, false); |
| gc.setForeground(oldForeground); |
| gc.setBackground(oldBackground); |
| event.detail &= ~SWT.BACKGROUND; |
| event.detail &= ~SWT.HOT; |
| }); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| /** |
| * On Windows/Mac, if columnWidth is not set via setWidth or pack, then items are not visible. |
| */ |
| @Test |
| public void column_noWidth_bug399522 () { |
| Shell shell = mkShell("Expected : You shouldn't see the column/item as column width not set yet."); |
| |
| final Table table = new Table(shell, SWT.BORDER); |
| table.setHeaderVisible(true); |
| |
| new TableItem(table, SWT.NONE).setText("Item1"); |
| TableColumn column1 = new TableColumn(table, SWT.NONE); |
| // column1.setWidth(10); // Setting column width (or packing) makes items visible. |
| |
| table.setSize(200, 200); |
| System.out.println(column1.handle); |
| |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void ownerDrawn_multiColumn_gc_snippet239 () { |
| Shell shell = mkShell("Verify that text is correctly drawn across 2 columns. 4 columns in total."); |
| shell.setText("Text spans two columns in a TableItem"); |
| shell.setLayout (new FillLayout()); |
| final Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); |
| table.setHeaderVisible(true); |
| int columnCount = 4; |
| for (int i=0; i<columnCount; i++) { |
| TableColumn column = new TableColumn(table, SWT.NONE); |
| System.out.println("Column " + i); |
| column.setText("Column " + i); |
| } |
| int itemCount = 8; |
| for (int i = 0; i < itemCount; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(0, "item "+i+" a"); |
| item.setText(3, "item "+i+" d"); |
| } |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| final String string = "text that spans two columns"; |
| GC gc = new GC(table); |
| final Point extent = gc.stringExtent(string); |
| gc.dispose(); |
| final Color red = display.getSystemColor(SWT.COLOR_RED); |
| Listener paintListener = event -> { |
| switch(event.type) { |
| case SWT.MeasureItem: { |
| if (event.index == 1 || event.index == 2) { |
| event.width = extent.x/2; |
| event.height = Math.max(event.height, extent.y + 2); |
| } |
| break; |
| } |
| case SWT.PaintItem: { |
| if (event.index == 1 || event.index == 2) { |
| int offset = 0; |
| if (event.index == 2) { |
| TableColumn column1 = table.getColumn(1); |
| offset = column1.getWidth(); |
| } |
| event.gc.setForeground(red); |
| int y = event.y + (event.height - extent.y)/2; |
| event.gc.drawString(string, event.x - offset, y, true); |
| } |
| break; |
| } |
| } |
| }; |
| table.addListener(SWT.MeasureItem, paintListener); |
| table.addListener(SWT.PaintItem, paintListener); |
| for (int i = 0; i < columnCount; i++) { |
| table.getColumn(i).pack(); |
| } |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void bug73812_tableColumn_getWidth_0 () { |
| Shell shell = mkShell("Verify that all columns are of same width. (100)."); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.setLayout(new FillLayout()); |
| |
| final Table tt = new Table(shell, SWT.FULL_SELECTION | SWT.MULTI | SWT.VIRTUAL); |
| tt.setLinesVisible(true); |
| tt.setHeaderVisible(true); |
| |
| for (int i = 0; i < 10; i++) { |
| TableColumn tc = new TableColumn(tt, SWT.NONE); |
| tc.setWidth(100); |
| System.out.println(tc.getWidth()); |
| tc.setWidth(tc.getWidth()); |
| tc.setText("Column " + i); |
| } |
| |
| for (int i = 0; i < 100; i++) { |
| new TableItem(tt, SWT.NONE); |
| } |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| /** |
| * Last column should be big enough so that text inside it can be read. |
| * Notion that getWidth() when called after setWidth() returns a different size. |
| */ |
| @Test |
| public void bug51079_setWidth_getWidth() { |
| Shell shell = mkShell("column SetGet Width : Make shell smaller and bigger. If you don't see COL_SIZE_ERROR in console, all is well."); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.setLayout(new FillLayout()); |
| StringBuilder sbBuffer = new StringBuilder(); |
| |
| final Composite comp = new Composite(shell, SWT.NONE); |
| final Table table = new Table(comp, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| final TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setText("Column 1"); |
| column1.setResizable(false); |
| final TableColumn column2 = new TableColumn(table, SWT.NONE); |
| column2.setText("Column 2"); |
| column2.setResizable(false); |
| for (int i = 0; i < 60; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| sbBuffer.append("M"); |
| item.setText(new String[] { "item 0 " + sbBuffer.toString() + " " + i, "item 1 " + i }); |
| } |
| |
| Consumer<Integer> setColumnWidths = (width) -> { |
| int c1w = (int)(width * 0.9); |
| column1.setWidth(c1w); |
| int c1wPost = column1.getWidth(); |
| if (c1w != c1wPost) |
| System.err.println("COL_SIZE_ERROR 1 Expected:" + c1w + " actual:" + c1wPost); |
| |
| int c2w = width - column1.getWidth(); |
| column2.setWidth(c2w); |
| int c2wPost = column2.getWidth(); |
| if (c2w != c2wPost) |
| System.err.println("COL_SIZE_ERROR 2 Expected:" + c2w + " actual:" + column2.getWidth()); |
| }; |
| |
| comp.addControlListener(new ControlAdapter() |
| { |
| @Override |
| public void controlResized(ControlEvent e) |
| { |
| Rectangle area = table.getParent().getClientArea(); |
| Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| int width = area.width - 2 * table.getBorderWidth(); |
| if (preferredSize.y > area.height) |
| { |
| // Subtract the scrollbar width from the total column width |
| // if a vertical scrollbar will be required |
| Point vBarSize = table.getVerticalBar().getSize(); |
| width -= vBarSize.x; |
| } |
| Point oldSize = table.getSize(); |
| if (oldSize.x > area.width) |
| { |
| // table is getting smaller so make the columns |
| // smaller first and then resize the table to |
| // match the client area width |
| setColumnWidths.accept(width); |
| table.setSize(area.width, area.height); |
| } |
| else |
| { |
| // table is getting bigger so make the table |
| // bigger first and then make the columns wider |
| // to match the client area width |
| table.setSize(area.width, area.height); |
| setColumnWidths.accept(width); |
| } |
| } |
| }); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void basicTable_Snippet35() { |
| Shell shell = mkShell("Basic Table with a few items, no column, no headers"); |
| shell.setLayout(new FillLayout()); |
| Table table = new Table (shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); |
| for (int i=0; i<12; i++) { |
| TableItem item = new TableItem (table, 0); |
| item.setText ("Item " + i); |
| } |
| shell.setSize (SWIDTH, SHEIGHT); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| |
| |
| @Test |
| public void ownerDrawn_icons_on_right_side_of_column_Snippet230() { |
| Shell shell = mkShell("Verify icons are visible on all columns on right side. (on gtk3, icons are cut off Bug 531882)"); |
| knownToBeBrokenGtk3("On gtk3, icons in col 1 and 2 are cut off. Bug 531882"); |
| |
| final Image image = display.getSystemImage(SWT.ICON_INFORMATION); |
| shell.setLayout(new FillLayout ()); |
| Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| int columnCount = 3; |
| for (int i=0; i<columnCount; i++) { |
| TableColumn column = new TableColumn(table, SWT.NONE); |
| column.setText("Column " + i); |
| } |
| int itemCount = 8; |
| for(int i = 0; i < itemCount; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"item "+i+" a", "item "+i+" b", "item "+i+" c"}); |
| } |
| |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| Listener paintListener = event -> { |
| switch(event.type) { |
| case SWT.MeasureItem: { |
| Rectangle rect1 = image.getBounds(); |
| event.width += rect1.width; |
| event.height = Math.max(event.height, rect1.height + 2); |
| break; |
| } |
| case SWT.PaintItem: { |
| int x = event.x + event.width; |
| Rectangle rect2 = image.getBounds(); |
| int offset = Math.max(0, (event.height - rect2.height) / 2); |
| event.gc.drawImage(image, x, event.y + offset); |
| break; |
| } |
| } |
| }; |
| table.addListener(SWT.MeasureItem, paintListener); |
| table.addListener(SWT.PaintItem, paintListener); |
| |
| for(int i = 0; i < columnCount; i++) { |
| table.getColumn(i).pack(); |
| } |
| shell.setSize (SWIDTH, SHEIGHT); |
| shell.open(); |
| shell.addDisposeListener(e -> { |
| if(image != null) image.dispose(); |
| }); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void ownerDrawn_barChart_Snippet228() { |
| Shell shell = mkShell("Ensure you see bar-charts in 2nd column and they resize with shell."); |
| shell.setLayout(new FillLayout()); |
| final Table table = new Table(shell, SWT.BORDER); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setText("Bug Status"); |
| column1.setWidth(100); |
| final TableColumn column2 = new TableColumn(table, SWT.NONE); |
| column2.setText("Percent"); |
| column2.setWidth(200); |
| String[] labels = new String[]{"Resolved", "New", "Won't Fix", "Invalid"}; |
| for (int i=0; i<labels.length; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(labels[i]); |
| } |
| |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| table.addListener(SWT.PaintItem, new Listener() { |
| int[] percents = new int[] {50, 30, 5, 15}; |
| @Override |
| public void handleEvent(Event event) { |
| if (event.index == 1) { |
| GC gc = event.gc; |
| TableItem item = (TableItem)event.item; |
| int index = table.indexOf(item); |
| int percent = percents[index]; |
| Color foreground = gc.getForeground(); |
| Color background = gc.getBackground(); |
| gc.setForeground(display.getSystemColor(SWT.COLOR_RED)); |
| gc.setBackground(display.getSystemColor(SWT.COLOR_YELLOW)); |
| int width = (column2.getWidth() - 1) * percent / 100; |
| gc.fillGradientRectangle(event.x, event.y, width, event.height, true); |
| Rectangle rect2 = new Rectangle(event.x, event.y, width-1, event.height-1); |
| gc.drawRectangle(rect2); |
| gc.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND)); |
| String text = percent+"%"; |
| Point size = event.gc.textExtent(text); |
| int offset = Math.max(0, (event.height - size.y) / 2); |
| gc.drawText(text, event.x+2, event.y+offset, true); |
| gc.setForeground(background); |
| gc.setBackground(foreground); |
| } |
| } |
| }); |
| shell.setSize (SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void ownerDrawn_textAlignment_Snippet231 () { |
| Shell shell = mkShell("Ensure there is no cheese, also when hoving over items"); |
| final int COLUMN_COUNT = 4; |
| final int ITEM_COUNT = 8; |
| final int TEXT_MARGIN = 3; |
| shell.setLayout(new FillLayout()); |
| final Table table = new Table(shell, SWT.FULL_SELECTION); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| for (int i = 0; i < COLUMN_COUNT; i++) { |
| new TableColumn(table, SWT.NONE); |
| } |
| for (int i = 0; i < ITEM_COUNT; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| for (int j = 0; j < COLUMN_COUNT; j++) { |
| String string = "item " + i + " col " + j; |
| if ((i + j) % 3 == 1) { |
| string +="\nnew line1"; |
| } |
| if ((i + j) % 3 == 2) { |
| string +="\nnew line1\nnew line2"; |
| } |
| item.setText(j, string); |
| } |
| } |
| |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| table.addListener(SWT.MeasureItem, event -> { |
| TableItem item = (TableItem)event.item; |
| String text = item.getText(event.index); |
| Point size = event.gc.textExtent(text); |
| event.width = size.x + 2 * TEXT_MARGIN; |
| event.height = Math.max(event.height, size.y + TEXT_MARGIN); |
| }); |
| table.addListener(SWT.EraseItem, event -> event.detail &= ~SWT.FOREGROUND); |
| table.addListener(SWT.PaintItem, event -> { |
| TableItem item = (TableItem)event.item; |
| String text = item.getText(event.index); |
| /* center column 1 vertically */ |
| int yOffset = 0; |
| if (event.index == 1) { |
| Point size = event.gc.textExtent(text); |
| yOffset = Math.max(0, (event.height - size.y) / 2); |
| } |
| event.gc.drawText(text, event.x + TEXT_MARGIN, event.y + yOffset, true); |
| }); |
| |
| for (int i = 0; i < COLUMN_COUNT; i++) { |
| table.getColumn(i).pack(); |
| } |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void ownerDrawn_CustomItemHeight () { |
| Shell shell = mkShell("Ensure Item 3 (yellow) is bigger than the other items"); |
| int bigItem = 3; |
| |
| shell.setLayout(new FillLayout()); |
| shell.setSize (SWIDTH, SHEIGHT); |
| final Table table = new Table(shell, SWT.NONE); |
| table.setLinesVisible(true); |
| |
| |
| for (int i = 0; i < 5; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| if (i == bigItem) { |
| item.setText("Item " + bigItem + " has bigger height"); |
| item.setBackground(display.getSystemColor(SWT.COLOR_YELLOW)); |
| } |
| else { |
| item.setText("item " + i); |
| item.setBackground(display.getSystemColor(SWT.COLOR_DARK_GRAY)); |
| } |
| } |
| |
| /* |
| * NOTE: MeasureItem is called repeatedly. Therefore it is critical |
| * for performance that this method be as efficient as possible. |
| */ |
| table.addListener(SWT.MeasureItem, event -> { |
| int clientWidth = table.getClientArea().width; |
| event.height = event.gc.getFontMetrics().getHeight() * 2; // * table.indexOf((TableItem) event.item) to have different height rows. |
| event.width = clientWidth * 2; |
| |
| if (table.indexOf((TableItem) event.item) == bigItem) { |
| event.height *= 2; |
| } |
| }); |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| |
| /** |
| * Snippet 144 modified to auto-populate items when shell is activated instead. |
| */ |
| @Test |
| public void virtual_addManyItems_Snippet144 () { |
| final Shell shell = mkShell("Shell Should show and items should be populated in lazy way"); |
| shell.setSize (SWIDTH, SHEIGHT); |
| final int COUNT = 100000; |
| shell.setLayout(new RowLayout(SWT.VERTICAL)); |
| final Table table = new Table (shell, SWT.VIRTUAL | SWT.BORDER); |
| final Label label1 = new Label(shell, SWT.NONE); |
| table.addListener (SWT.SetData, event -> { |
| TableItem item = (TableItem) event.item; |
| int index = table.indexOf (item); |
| item.setText ("Item " + index); |
| label1.setText("Added " + item.getText()); |
| }); |
| table.setLayoutData (new RowData (shell.getBounds().width - 100, 400)); |
| final Label label2 = new Label(shell, SWT.NONE); |
| shell.addShellListener( new ShellAdapter() { |
| @Override |
| public void shellActivated(ShellEvent e) { |
| System.out.println("activated"); |
| long t1 = System.currentTimeMillis (); |
| table.setItemCount (COUNT); |
| long t2 = System.currentTimeMillis (); |
| label2.setText ("Items: " + COUNT + ", Time: " + (t2 - t1) + " (ms)"); |
| shell.layout (); |
| } |
| }); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void column_headers_Snippet38() { |
| Shell shell = mkShell("Matrix with rows & columns and columns with description. (BUG gtk2/3 text seems slightly cut off, Bug 531875)"); |
| knownToBeBrokenGtk("Text in column is cut off at the moment. See Bug 531875"); |
| |
| shell.setLayout(new GridLayout()); |
| Table table = new Table (shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); |
| table.setLinesVisible (true); |
| table.setHeaderVisible (true); |
| GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); |
| data.heightHint = 200; |
| table.setLayoutData(data); |
| String[] titles = {" ", "C", "!", "Description", "Resource", "In Folder", "Location"}; |
| for (int i=0; i<titles.length; i++) { |
| TableColumn column = new TableColumn (table, SWT.NONE); |
| column.setText (titles [i]); |
| } |
| int count = 128; |
| 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 (); |
| } |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| |
| @Test |
| public void column_header_icons_Snippet297() { |
| Image images[] = new Image[] { |
| display.getSystemImage(SWT.ICON_INFORMATION), |
| display.getSystemImage(SWT.ICON_ERROR), |
| display.getSystemImage(SWT.ICON_QUESTION), |
| display.getSystemImage(SWT.ICON_WARNING), |
| }; |
| String[] titles = {"Information", "Error", "Question", "Warning"}; |
| String[] questions = {"who?", "what?", "where?", "when?", "why?"}; |
| Shell shell = new Shell (display); |
| shell.setLayout(new GridLayout()); |
| Table table = new Table (shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION); |
| GridData data = new GridData (SWT.FILL, SWT.FILL, true, true); |
| data.heightHint = 200; |
| table.setLayoutData (data); |
| table.setLinesVisible (true); |
| table.setHeaderVisible (true); |
| |
| for (int i=0; i<titles.length; i++) { |
| TableColumn column = new TableColumn (table, SWT.NONE); |
| column.setText (titles [i]); |
| column.setImage(images [i]); |
| } |
| |
| int count = 128; |
| for (int i=0; i<count; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText (0, "some info"); |
| item.setText (1, "error #" + i); |
| item.setText (2, questions [i % questions.length]); |
| item.setText (3, "look out!"); |
| } |
| for (int i=0; i<titles.length; i++) { |
| table.getColumn (i).pack (); |
| } |
| |
| table.setHeaderBackground(display.getSystemColor(SWT.COLOR_BLUE)); |
| table.setHeaderForeground(display.getSystemColor(SWT.COLOR_RED)); |
| |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| /** |
| * Based on Snippet 106 with some modificaitons. |
| */ |
| @Test |
| public void column_dynamically_added_after_shellOpened_Snippet106() { |
| Shell shell = mkShell("Verify dynamic column (2) was added properly."); |
| |
| final Table table = new Table (shell, SWT.BORDER | SWT.MULTI); |
| table.setHeaderVisible (true); |
| for (int i=0; i<4; i++) { |
| TableColumn column = new TableColumn (table, SWT.NONE); |
| column.setText ("Column " + i); |
| } |
| final TableColumn [] columns = table.getColumns (); |
| for (int i=0; i<12; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| for (int j=0; j<columns.length; j++) { |
| item.setText (j, "Item " + i); |
| } |
| } |
| for (int i=0; i<columns.length; i++) columns [i].pack (); |
| Button button = new Button (shell, SWT.PUSH); |
| final int index = 1; |
| button.setText ("Insert Column " + index + "a"); |
| |
| AtomicBoolean columnAdded = new AtomicBoolean(false); |
| shell.addShellListener(new ShellAdapter() { |
| @Override |
| public void shellActivated(ShellEvent e) { |
| if (!columnAdded.get()) { |
| columnAdded.set(true); |
| TableColumn column = new TableColumn (table, SWT.NONE, index); |
| column.setImage(display.getSystemImage(SWT.ICON_WARNING)); //added to make it easier to spot in a test. |
| column.setText ("Column " + index + " added after shellopen"); |
| TableItem [] items = table.getItems (); |
| for (int i=0; i<items.length; i++) { |
| items [i].setText (index, "Item " + i + " added"); |
| } |
| column.pack (); |
| } |
| } |
| }); |
| |
| shell.setSize (SWIDTH, SHEIGHT); |
| Rectangle shellClientArea = shell.getClientArea(); |
| table.setSize(shellClientArea.width, shellClientArea.height); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void column_dynamic_resize() { |
| Shell shell = mkShell("Try resizing shell. Columns should resize as you resize shell"); |
| shell.setLayout(new FillLayout()); |
| |
| final Composite comp = new Composite(shell, SWT.NONE); |
| final Table table = new Table(comp, SWT.BORDER | SWT.V_SCROLL); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| final TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setText("Column 1"); |
| final TableColumn column2 = new TableColumn(table, SWT.NONE); |
| column2.setText("Column 2"); |
| for (int i = 0; i < 10; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"item 0" + i, "item 1"+i}); |
| } |
| comp.addControlListener(ControlListener.controlResizedAdapter(e -> { |
| Rectangle area = comp.getClientArea(); |
| Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| ScrollBar vBar = table.getVerticalBar(); |
| int width = area.width - table.computeTrim(0, 0, 0, 0).width - vBar.getSize().x; |
| if (size.y > area.height + table.getHeaderHeight()) { |
| // Subtract the scrollbar width from the total column width |
| // if a vertical scrollbar will be required |
| Point vBarSize = vBar.getSize(); |
| width -= vBarSize.x; |
| } |
| Point oldSize = table.getSize(); |
| if (oldSize.x > area.width) { |
| // table is getting smaller so make the columns |
| // smaller first and then resize the table to |
| // match the client area width |
| column1.setWidth(width / 3); |
| column2.setWidth(width - column1.getWidth()); |
| table.setSize(area.width, area.height); |
| } else { |
| // table is getting bigger so make the table |
| // bigger first and then make the columns wider |
| // to match the client area width |
| table.setSize(area.width, area.height); |
| column1.setWidth(width / 3); |
| column2.setWidth(width - column1.getWidth()); |
| } |
| })); |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void measureItem_custom_Column_width_onPack_Snippet272() { |
| Shell shell = mkShell("Double click on column boundary '|', observe column get's bigger"); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.setLayout(new FillLayout()); |
| Table table = new Table(shell, SWT.NONE); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| final TableColumn column0 = new TableColumn(table, SWT.NONE); |
| column0.setWidth(110); |
| column0.setText("2x Click pipe ->"); |
| final TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setWidth(110); |
| column0.addListener(SWT.Selection, event -> column0.pack()); |
| column1.addListener(SWT.Selection, event -> column1.pack()); |
| for (int i = 0; i < 5; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(0, "item " + i + " col 0"); |
| item.setText(1, "item " + i + " col 1"); |
| } |
| |
| /* |
| * NOTE: MeasureItem is called repeatedly. Therefore it is critical |
| * for performance that this method be as efficient as possible. |
| */ |
| table.addListener(SWT.MeasureItem, event -> event.width *= 4); // This guy makes the difference. |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void checkBoxes() { |
| Shell shell = mkShell("You should see some checkboxes"); |
| shell.setLayout(new FillLayout()); |
| Table table = new Table (shell, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); |
| for (int i=0; i<12; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText ("Item " + i); |
| } |
| Rectangle clientArea = shell.getClientArea (); |
| table.setBounds (clientArea.x, clientArea.y, 600, 500); |
| |
| final Label label = new Label(shell, SWT.NONE); |
| |
| table.addListener (SWT.Selection, event -> { |
| String string = event.detail == SWT.CHECK ? "Checked" : "Selected"; |
| label.setText(event.item + " " + string); |
| }); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void color_singleColumn() { |
| Shell shell = mkShell("Header and content should be colored red and blue. Column header should be of a darker color."); |
| shell.setLayout(new FillLayout()); |
| |
| Table table = new Table (shell, SWT.None); |
| table.setHeaderVisible(true); |
| TableColumn column = new TableColumn(table, SWT.LEFT); |
| column.setText("Column header has darker colors."); |
| column.pack(); |
| |
| for (int i = 0; i < 200; i++) { |
| TableItem item = new TableItem(table, SWT.None); |
| item.setText("Item " + i); |
| } |
| |
| table.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); |
| table.setForeground(display.getSystemColor(SWT.COLOR_RED)); |
| |
| table.setHeaderBackground(display.getSystemColor(SWT.COLOR_DARK_BLUE)); |
| table.setHeaderForeground(display.getSystemColor(SWT.COLOR_DARK_RED)); |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void color_MultipleColumn() { |
| Shell shell = mkShell("Header and content should be colored red and blue. Column header should be of a darker color."); |
| shell.setLayout(new FillLayout()); |
| |
| Table table = new Table (shell, SWT.None); |
| table.setHeaderVisible(true); |
| TableColumn column = new TableColumn(table, SWT.LEFT); |
| column.setText("Column 1"); |
| column.pack(); |
| |
| TableColumn column2 = new TableColumn(table, SWT.LEFT); |
| column2.setText("Column 2"); |
| column2.pack(); |
| |
| for (int i = 0; i < 200; i++) { |
| TableItem item = new TableItem(table, SWT.None); |
| item.setText(new String[] {"Item " + i, "Item col2: " + i}); |
| } |
| |
| table.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); |
| table.setForeground(display.getSystemColor(SWT.COLOR_RED)); |
| |
| table.setHeaderBackground(display.getSystemColor(SWT.COLOR_DARK_BLUE)); |
| table.setHeaderForeground(display.getSystemColor(SWT.COLOR_DARK_RED)); |
| |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void color_differentCells_Snippet129 () { |
| Shell shell = mkShell("Table cells should be of different colors"); |
| |
| Color red = display.getSystemColor(SWT.COLOR_RED); |
| Color blue = display.getSystemColor(SWT.COLOR_BLUE); |
| Color white = display.getSystemColor(SWT.COLOR_WHITE); |
| Color gray = display.getSystemColor(SWT.COLOR_GRAY); |
| shell.setLayout(new FillLayout()); |
| Table table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION); |
| table.setBackground(gray); |
| TableColumn column1 = new TableColumn(table, SWT.NONE); |
| TableColumn column2 = new TableColumn(table, SWT.NONE); |
| TableColumn column3 = new TableColumn(table, SWT.NONE); |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"entire","row","red foreground"}); |
| item.setForeground(red); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"entire","row","red background"}); |
| item.setBackground(red); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"entire","row","white fore/red back"}); |
| item.setForeground(white); |
| item.setBackground(red); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"normal","blue foreground","red foreground"}); |
| item.setForeground(1, blue); |
| item.setForeground(2, red); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"normal","blue background","red background"}); |
| item.setBackground(1, blue); |
| item.setBackground(2, red); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"white fore/blue back","normal","white fore/red back"}); |
| item.setForeground(0, white); |
| item.setBackground(0, blue); |
| item.setForeground(2, white); |
| item.setBackground(2, red); |
| |
| column1.pack(); |
| column2.pack(); |
| column3.pack(); |
| |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void programaticScrolling_Snippet52() { |
| Shell shell = mkShell("Table should be scrolled down to 100th item"); |
| Table table = new Table (shell, SWT.BORDER | SWT.MULTI); |
| Rectangle clientArea = shell.getClientArea (); |
| table.setBounds (clientArea.x, clientArea.y,800, 600); |
| for (int i=0; i<128; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText ("Item " + i); |
| } |
| table.setSelection (100); // <<< This is what we're testing. |
| shell.pack (); |
| shell.open (); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void sort_by_column_Snippet2() { |
| Shell shell = mkShell("Click on columns to verify items are sorted properly"); |
| shell.setLayout(new FillLayout()); |
| |
| final Table table = new Table(shell, SWT.BORDER); |
| table.setHeaderVisible(true); |
| final TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setText("Column 1"); |
| final TableColumn column2 = new TableColumn(table, SWT.NONE); |
| column2.setText("Column 2"); |
| TableItem item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"a", "3"}); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"b", "2"}); |
| item = new TableItem(table, SWT.NONE); |
| item.setText(new String[] {"c", "1"}); |
| column1.setWidth(100); |
| column2.setWidth(100); |
| Listener sortListener = e -> { |
| TableItem[] items = table.getItems(); |
| Collator collator = Collator.getInstance(Locale.getDefault()); |
| TableColumn column = (TableColumn)e.widget; |
| int index = column == column1 ? 0 : 1; |
| for (int i = 1; i < items.length; i++) { |
| String value1 = items[i].getText(index); |
| for (int j = 0; j < i; j++){ |
| String value2 = items[j].getText(index); |
| if (collator.compare(value1, value2) < 0) { |
| String[] values = {items[i].getText(0), items[i].getText(1)}; |
| items[i].dispose(); |
| TableItem item1 = new TableItem(table, SWT.NONE, j); |
| item1.setText(values); |
| items = table.getItems(); |
| break; |
| } |
| } |
| } |
| table.setSortColumn(column); |
| }; |
| column1.addListener(SWT.Selection, sortListener); |
| column2.addListener(SWT.Selection, sortListener); |
| table.setSortColumn(column1); |
| table.setSortDirection(SWT.UP); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void sort_by_columnt_virtual_Snippet192 () { |
| Shell shell = mkShell("Click on column heading to sort"); |
| // initialize data with keys and random values |
| int size = 100; |
| Random random = new Random(); |
| final int[][] data = new int[size][]; |
| for (int i = 0; i < data.length; i++) { |
| data[i] = new int[] {i, random.nextInt()}; |
| } |
| // create a virtual table to display data |
| shell.setLayout(new FillLayout()); |
| final Table table = new Table(shell, SWT.VIRTUAL); |
| table.setHeaderVisible(true); |
| table.setLinesVisible(true); |
| table.setItemCount(size); |
| final TableColumn column1 = new TableColumn(table, SWT.NONE); |
| column1.setText("Key"); |
| column1.setWidth(200); |
| final TableColumn column2 = new TableColumn(table, SWT.NONE); |
| column2.setText("Value"); |
| column2.setWidth(200); |
| table.addListener(SWT.SetData, e -> { |
| TableItem item = (TableItem) e.item; |
| int index = table.indexOf(item); |
| int[] datum = data[index]; |
| item.setText(new String[] {Integer.toString(datum[0]), |
| Integer.toString(datum[1]) }); |
| }); |
| // Add sort indicator and sort data when column selected |
| Listener sortListener = e -> { |
| // determine new sort column and direction |
| TableColumn sortColumn = table.getSortColumn(); |
| TableColumn currentColumn = (TableColumn) e.widget; |
| int dir = table.getSortDirection(); |
| if (sortColumn == currentColumn) { |
| dir = dir == SWT.UP ? SWT.DOWN : SWT.UP; |
| } else { |
| table.setSortColumn(currentColumn); |
| dir = SWT.UP; |
| } |
| // sort the data based on column and direction |
| final int index = currentColumn == column1 ? 0 : 1; |
| final int direction = dir; |
| Arrays.sort(data, (a, b) -> { |
| if (a[index] == b[index]) return 0; |
| if (direction == SWT.UP) { |
| return a[index] < b[index] ? -1 : 1; |
| } |
| return a[index] < b[index] ? 1 : -1; |
| }); |
| // update data displayed in table |
| table.setSortDirection(dir); |
| table.clearAll(); |
| }; |
| column1.addListener(SWT.Selection, sortListener); |
| column2.addListener(SWT.Selection, sortListener); |
| table.setSortColumn(column1); |
| table.setSortDirection(SWT.UP); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void icons_ofDiffSize_inItems_Snippet349() { |
| Shell shell = mkShell("Verify that items have icons of different sizes and icons are not cut off"); |
| |
| BiFunction<Integer, Integer, Image> createImage = (width, height) -> { |
| Image result = new Image(display, width, height); |
| GC gc = new GC(result); |
| for (int x = -height; x < width; x += 4) { |
| gc.drawLine(x, 0, x + height, height); |
| } |
| gc.dispose(); |
| return result; |
| }; |
| |
| final int COLUMN_COUNT = 3; |
| final int TEXT_MARGIN = 3; |
| final String KEY_WIDTHS = "widths"; |
| final String KEY_IMAGES = "images"; |
| |
| Image[] images = new Image[4]; |
| images[0] = createImage.apply(16, 16); |
| images[1] = createImage.apply(32, 16); |
| images[2] = createImage.apply(48, 16); |
| |
| shell.setLayout(new FillLayout()); |
| Table table = new Table(shell, SWT.NONE); |
| for (int i = 0; i < COLUMN_COUNT; i++) { |
| new TableColumn(table, SWT.NONE); |
| } |
| for (int i = 0; i < 8; i++) { |
| TableItem item = new TableItem(table, SWT.NONE); |
| Image[] itemImages = new Image[COLUMN_COUNT]; |
| item.setData(KEY_IMAGES, itemImages); |
| for (int j = 0; j < COLUMN_COUNT; j++) { |
| item.setText(j, "item " + i + " col " + j); |
| itemImages[j] = images[(i * COLUMN_COUNT + j) % images.length]; |
| } |
| } |
| |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| final int itemHeight = table.getItemHeight(); |
| GC gc = new GC(table); |
| FontMetrics metrics = gc.getFontMetrics(); |
| final int fontHeight = metrics.getHeight(); |
| gc.dispose(); |
| Listener paintListener = event -> { |
| switch (event.type) { |
| case SWT.MeasureItem: { |
| int column1 = event.index; |
| TableItem item1 = (TableItem)event.item; |
| Image[] images1 = (Image[])item1.getData(KEY_IMAGES); |
| Image image1 = images1[column1]; |
| if (image1 == null) { |
| /* don't change the native-calculated event.width */ |
| break; |
| } |
| int[] cachedWidths = (int[])item1.getData(KEY_WIDTHS); |
| if (cachedWidths == null) { |
| cachedWidths = new int[COLUMN_COUNT]; |
| item1.setData(KEY_WIDTHS, cachedWidths); |
| } |
| if (cachedWidths[column1] == 0) { |
| int width = image1.getBounds().width + 2 * TEXT_MARGIN; |
| GC gc1 = new GC(item1.getParent()); |
| width += gc1.stringExtent(item1.getText()).x; |
| gc1.dispose(); |
| cachedWidths[column1] = width; |
| } |
| event.width = cachedWidths[column1]; |
| break; |
| } |
| case SWT.EraseItem: { |
| int column2 = event.index; |
| TableItem item2 = (TableItem)event.item; |
| Image[] images2 = (Image[])item2.getData(KEY_IMAGES); |
| Image image2 = images2[column2]; |
| if (image2 == null) { |
| break; |
| } |
| /* disable the native drawing of this item */ |
| event.detail &= ~SWT.FOREGROUND; |
| break; |
| } |
| case SWT.PaintItem: { |
| int column3 = event.index; |
| TableItem item3 = (TableItem)event.item; |
| Image[] images3 = (Image[])item3.getData(KEY_IMAGES); |
| Image image3 = images3[column3]; |
| if (image3 == null) { |
| /* this item is drawn natively, don't touch it*/ |
| break; |
| } |
| |
| int x = event.x; |
| event.gc.drawImage(image3, x, event.y + (itemHeight - image3.getBounds().height) / 2); |
| x += image3.getBounds().width + TEXT_MARGIN; |
| event.gc.drawString(item3.getText(column3), x, event.y + (itemHeight - fontHeight) / 2); |
| break; |
| } |
| } |
| }; |
| table.addListener(SWT.MeasureItem, paintListener); |
| table.addListener(SWT.EraseItem, paintListener); |
| table.addListener(SWT.PaintItem, paintListener); |
| |
| for (int i = 0; i < COLUMN_COUNT; i++) { |
| table.getColumn(i).pack(); |
| } |
| |
| shell.addDisposeListener(e -> { |
| for (int i = 0; i < images.length; i++) { |
| if (images[i] != null) { |
| images[i].dispose(); |
| } |
| } |
| }); |
| |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void styledItems_Snippet236() { |
| Shell shell = mkShell("Verify tableitems with custom styleText control looks proper & multiple items can be selected"); |
| shell.setLayout(new FillLayout()); |
| Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); |
| table.setLinesVisible(true); |
| for(int i = 0; i < 10; i++) { |
| new TableItem(table, SWT.NONE); |
| } |
| final TextLayout textLayout = new TextLayout(display); |
| textLayout.setText("SWT: Standard Widget Toolkit"); |
| Font font1 = new Font(display, "Tahoma", 14, SWT.BOLD); |
| Font font2 = new Font(display, "Tahoma", 10, SWT.NORMAL); |
| Font font3 = new Font(display, "Tahoma", 14, SWT.ITALIC); |
| TextStyle style1 = new TextStyle(font1, display.getSystemColor(SWT.COLOR_BLUE), null); |
| TextStyle style2 = new TextStyle(font2, display.getSystemColor(SWT.COLOR_MAGENTA), null); |
| TextStyle style3 = new TextStyle(font3, display.getSystemColor(SWT.COLOR_RED), null); |
| textLayout.setStyle(style1, 0, 0); textLayout.setStyle(style1, 5, 12); |
| textLayout.setStyle(style2, 1, 1); textLayout.setStyle(style2, 14, 19); |
| textLayout.setStyle(style3, 2, 2); textLayout.setStyle(style3, 21, 27); |
| |
| /* |
| * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. |
| * Therefore, it is critical for performance that these methods be |
| * as efficient as possible. |
| */ |
| table.addListener(SWT.PaintItem, event -> textLayout.draw(event.gc, event.x, event.y)); |
| final Rectangle textLayoutBounds = textLayout.getBounds(); |
| table.addListener(SWT.MeasureItem, e -> { |
| e.width = textLayoutBounds.width + 2; |
| e.height = textLayoutBounds.height + 2; |
| }); |
| shell.setSize (SWIDTH, SHEIGHT); |
| shell.open(); |
| shell.addDisposeListener(e -> { |
| font1.dispose(); |
| font2.dispose(); |
| font3.dispose(); |
| textLayout.dispose(); |
| }); |
| mainLoop(shell); |
| } |
| |
| @Test |
| public void cout_visible_items_Snippet253 () { |
| final Shell shell = mkShell("Ensure correct item count is displayed in count. Try resizing shell to show 15 items, it should show 15. Gtk3 issues"); |
| knownToBeBrokenGtk3("On gtk3, the measure is off, see bug 531884"); |
| |
| FillLayout layout = new FillLayout (SWT.VERTICAL); |
| shell.setLayout (layout); |
| final Table table = new Table (shell, SWT.NONE); |
| for (int i=0; i<32; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText ("Item " + (i+1) + " is quite long"); |
| } |
| final Button button = new Button (shell, SWT.PUSH); |
| |
| Runnable fixCount = () -> { |
| Rectangle rect = table.getClientArea (); |
| int itemHeight = table.getItemHeight (); |
| int headerHeight = table.getHeaderHeight (); |
| int visibleCount = (rect.height - headerHeight + itemHeight - 1) / itemHeight; |
| button.setText ("Visible Items [" + visibleCount + "]"); |
| }; |
| |
| button.setText ("Visible Items []"); |
| button.addListener (SWT.Selection, e -> { |
| fixCount.run(); |
| }); |
| |
| shell.addControlListener(new ControlAdapter() { |
| @Override |
| public void controlResized(ControlEvent e) { |
| fixCount.run(); |
| } |
| }); |
| shell.addShellListener(new ShellAdapter() { |
| @Override |
| public void shellActivated(ShellEvent e) { |
| fixCount.run(); |
| } |
| }); |
| // setSize(..)_ affects bug/snippet behaviour. |
| shell.setSize(1160, 820); //820 => ~15 items or so, depending on your theme. |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| |
| /** Snippet 149 was modified. |
| * - No added columns. |
| * - Button instead of progress bar. |
| */ |
| @Test |
| public void tableEditor_multiple_controls_Snippet149 () { |
| knownToBeBrokenGtk3("Snippet is broken on Gtk3. See Bug 531885"); |
| Shell shell = mkShell("Items should be replaced with Buttons (broken on Gtk3, Bug 531885)"); |
| shell.setLayout (new FillLayout ()); |
| Table table = new Table (shell, SWT.BORDER); |
| for (int i = 0; i < 20; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText ("Task " + i); |
| Button button = new Button (table, SWT.NONE); |
| button.setText("hello world " + i); |
| button.setVisible(true); |
| button.addSelectionListener(new SelectionListener() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| System.out.println("Button pressed"); |
| } |
| @Override |
| public void widgetDefaultSelected(SelectionEvent e) { |
| } |
| }); |
| TableEditor editor = new TableEditor (table); |
| editor.grabHorizontal = editor.grabVertical = true; |
| editor.setEditor (button, item, 0); |
| } |
| shell.setSize (SWIDTH, SHEIGHT); |
| shell.open(); |
| mainLoop(shell); |
| } |
| |
| |
| @Test |
| public void tableEditor_dynamically_created_Snippet124() { |
| Shell shell = mkShell("Verify you can edit cells"); |
| shell.setLayout (new FillLayout ()); |
| final 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<3; i++) { |
| TableItem item = new TableItem (table, SWT.NONE); |
| item.setText(new String [] {"" + i, "" + i , "" + i}); |
| } |
| final TableEditor editor = new TableEditor (table); |
| editor.horizontalAlignment = SWT.LEFT; |
| editor.grabHorizontal = true; |
| table.addListener (SWT.MouseDown, event -> { |
| Rectangle clientArea = table.getClientArea (); |
| Point pt = new Point (event.x, event.y); |
| int index = table.getTopIndex (); |
| while (index < table.getItemCount ()) { |
| boolean visible = false; |
| final TableItem item = table.getItem (index); |
| for (int i=0; i<table.getColumnCount (); i++) { |
| Rectangle rect = item.getBounds (i); |
| if (rect.contains (pt)) { |
| final int column = i; |
| final Text text = new Text (table, SWT.NONE); |
| Listener textListener = e -> { |
| switch (e.type) { |
| case SWT.FocusOut: |
| item.setText (column, text.getText ()); |
| text.dispose (); |
| break; |
| case SWT.Traverse: |
| switch (e.detail) { |
| case SWT.TRAVERSE_RETURN: |
| item.setText (column, text.getText ()); |
| //FALL THROUGH |
| case SWT.TRAVERSE_ESCAPE: |
| text.dispose (); |
| e.doit = false; |
| } |
| break; |
| } |
| }; |
| text.addListener (SWT.FocusOut, textListener); |
| text.addListener (SWT.Traverse, textListener); |
| editor.setEditor (text, item, i); |
| text.setText (item.getText (i)); |
| text.selectAll (); |
| text.setFocus (); |
| return; |
| } |
| if (!visible && rect.intersects (clientArea)) { |
| visible = true; |
| } |
| } |
| if (!visible) return; |
| index++; |
| } |
| }); |
| shell.setSize(SWIDTH, SHEIGHT); |
| shell.open (); |
| mainLoop(shell); |
| } |
| } |
| |