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 }