1 /* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 import java.awt.BorderLayout; 23 import java.awt.FlowLayout; 24 import java.awt.Color; 25 import java.awt.Dialog; 26 import javax.swing.JDialog; 27 import javax.swing.JPanel; 28 import javax.swing.JFrame; 29 import javax.swing.JTable; 30 import javax.swing.JTextArea; 31 import javax.swing.JButton; 32 import javax.swing.table.TableModel; 33 import javax.swing.JScrollPane; 34 import javax.swing.table.AbstractTableModel; 35 import javax.swing.SwingUtilities; 36 37 /** 38 * @test 39 * @bug 8081491 40 * @summary Scrolling a JTable creates artifacts 41 * @run main/manual JTableScrollTest 42 */ 43 public class JTableScrollTest { 44 static JFrame frame = new JFrame(); 45 public static void main(String[] args) throws Exception { 46 SwingUtilities.invokeAndWait(new Runnable() { 47 48 @Override 49 public void run() { 50 doTest(JTableScrollTest::createTable); 51 } 52 }); 53 } 54 55 private static void createTable() { 56 // final 57 final String[] names = { 58 new String("first_name"), 59 new String("last_name"), 60 new String("favorite_color"), 61 new String("favorite_food") 62 }; 63 64 // Create the dummy data (a few rows of names) 65 final Object[][] data = { 66 {"Mike", "Albers", "green", "strawberry"}, 67 {"Mark", "Andrews", "blue", "grapes"}, 68 {"Brian", "Beck", "black", "raspberry"}, 69 {"Lara", "Bunni", "red", "strawberry"}, 70 {"Roger", "Brinkley", "blue", "peach"}, 71 {"Brent", "Christian", "black", "broccoli"}, 72 {"Mark", "Davidson", "darkgreen", "asparagus"}, 73 {"Jeff", "Dinkins", "blue", "kiwi"}, 74 {"Ewan", "Dinkins", "yellow", "strawberry"}, 75 {"Amy", "Fowler", "violet", "raspberry"}, 76 {"Hania", "Gajewska", "purple", "raspberry"}, 77 {"David", "Geary", "blue", "watermelon"}, 78 {"Ryan", "Gosling", "pink", "donut"}, 79 {"Eric", "Hawkes", "blue", "pickle"}, 80 {"Shannon", "Hickey", "green", "grapes"}, 81 {"Earl", "Johnson", "green", "carrot"}, 82 {"Robi", "Khan", "green", "apple"}, 83 {"Robert", "Kim", "blue", "strawberry"}, 84 {"Janet", "Koenig", "turquoise", "peach"}, 85 {"Jeff", "Kesselman", "blue", "pineapple"}, 86 {"Onno", "Kluyt", "orange", "broccoli"}, 87 {"Peter", "Korn", "sunpurple", "sparegrass"}, 88 {"Rick", "Levenson", "black", "raspberry"}, 89 {"Brian", "Lichtenwalter", "blue", "pear"}, 90 {"Malini", "Minasandram", "beige", "corn"}, 91 {"Michael", "Martak", "green", "strawberry"}, 92 {"David", "Mendenhall", "forestgreen", "peach"}, 93 {"Phil", "Milne", "pink", "banana"}, 94 {"Lynn", "Monsanto", "cybergreen", "peach"}, 95 {"Hans", "Muller", "rustred", "pineapple"}, 96 {"Joshua", "Outwater", "blue", "pineapple"}, 97 {"Tim", "Prinzing", "blue", "pepper"}, 98 {"Raj", "Premkumar", "blue", "broccoli"}, 99 {"Howard", "Rosen", "green", "strawberry"}, 100 {"Ray", "Ryan", "black", "banana"}, 101 {"Georges", "Saab", "aqua", "cantaloupe"}, 102 {"Tom", "Santos", "blue", "pepper"}, 103 {"Rich", "Schiavi", "blue", "pepper"}, 104 {"Nancy", "Schorr", "green", "watermelon"}, 105 {"Keith", "Sprochi", "darkgreen", "watermelon"}, 106 {"Matt", "Tucker", "eblue", "broccoli"}, 107 {"Dmitri", "Trembovetski", "red", "tomato"}, 108 {"Scott", "Violet", "violet", "banana"}, 109 {"Kathy", "Walrath", "darkgreen", "pear"}, 110 }; 111 112 // Create a model of the data. 113 TableModel dataModel = new AbstractTableModel() { 114 public int getColumnCount() { return names.length; } 115 public int getRowCount() { return data.length;} 116 public Object getValueAt(int row, int col) {return data[row][col];} 117 public String getColumnName(int column) {return names[column];} 118 public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} 119 public boolean isCellEditable(int row, int col) {return col != 5;} 120 public void setValueAt(Object aValue, int row, int column) { data[row][column] = aValue; } 121 }; 122 123 // Create the table 124 JTable tableView = new JTable(dataModel); 125 tableView.setBackground(Color.WHITE); 126 tableView.setForeground(Color.BLACK); 127 tableView.setSize(600, 800); 128 JScrollPane scrollpane = new JScrollPane(tableView); 129 frame.add(scrollpane); 130 frame.pack(); 131 frame.setVisible(true); 132 } 133 134 private static void doTest(Runnable action) { 135 String description = 136 "JTable with rows will be displayed along with scrollbar.\n" 137 + "Scroll the table. Verify no arifacts are shown and rows.\n" 138 + " are correctly displayed."; 139 final JDialog dialog = new JDialog(); 140 dialog.setTitle("ScrollArtifactTest "); 141 JTextArea textArea = new JTextArea(description); 142 textArea.setEditable(false); 143 final JButton testButton = new JButton("Create Table"); 144 final JButton passButton = new JButton("PASS"); 145 passButton.setEnabled(false); 146 passButton.addActionListener((e) -> { 147 dialog.dispose(); 148 if (frame != null) { 149 frame.setVisible(false); 150 frame.dispose(); 151 } 152 }); 153 final JButton failButton = new JButton("FAIL"); 154 failButton.setEnabled(false); 155 failButton.addActionListener((e) -> { 156 dialog.dispose(); 157 if (frame != null) { 158 frame.setVisible(false); 159 frame.dispose(); 160 } 161 throw new RuntimeException("Scrollbar artifact shown"); 162 }); 163 testButton.addActionListener((e) -> { 164 testButton.setEnabled(false); 165 action.run(); 166 passButton.setEnabled(true); 167 failButton.setEnabled(true); 168 }); 169 JPanel mainPanel = new JPanel(new BorderLayout()); 170 mainPanel.add(textArea, BorderLayout.CENTER); 171 JPanel buttonPanel = new JPanel(new FlowLayout()); 172 buttonPanel.add(testButton); 173 buttonPanel.add(passButton); 174 buttonPanel.add(failButton); 175 mainPanel.add(buttonPanel, BorderLayout.SOUTH); 176 dialog.add(mainPanel); 177 dialog.pack(); 178 dialog.setVisible(true); 179 } 180 181 182 }