[4] | 1 | /* |
---|
| 2 | * This program is free software; you can redistribute it and/or modify |
---|
| 3 | * it under the terms of the GNU General Public License as published by |
---|
| 4 | * the Free Software Foundation; either version 2 of the License, or |
---|
| 5 | * (at your option) any later version. |
---|
| 6 | * |
---|
| 7 | * This program is distributed in the hope that it will be useful, |
---|
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 10 | * GNU General Public License for more details. |
---|
| 11 | * |
---|
| 12 | * You should have received a copy of the GNU General Public License |
---|
| 13 | * along with this program; if not, write to the Free Software |
---|
| 14 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
| 15 | */ |
---|
| 16 | |
---|
| 17 | /* |
---|
| 18 | * LegendPanel.java |
---|
| 19 | * Copyright (C) 2000 University of Waikato, Hamilton, New Zealand |
---|
| 20 | * |
---|
| 21 | */ |
---|
| 22 | |
---|
| 23 | package weka.gui.visualize; |
---|
| 24 | |
---|
| 25 | import weka.core.FastVector; |
---|
| 26 | import weka.core.Instances; |
---|
| 27 | |
---|
| 28 | import java.awt.BorderLayout; |
---|
| 29 | import java.awt.Color; |
---|
| 30 | import java.awt.Component; |
---|
| 31 | import java.awt.Dimension; |
---|
| 32 | import java.awt.Graphics; |
---|
| 33 | import java.awt.GridBagConstraints; |
---|
| 34 | import java.awt.GridBagLayout; |
---|
| 35 | import java.awt.Insets; |
---|
| 36 | import java.awt.event.MouseAdapter; |
---|
| 37 | import java.awt.event.MouseEvent; |
---|
| 38 | |
---|
| 39 | import javax.swing.JColorChooser; |
---|
| 40 | import javax.swing.JLabel; |
---|
| 41 | import javax.swing.JPanel; |
---|
| 42 | import javax.swing.JScrollPane; |
---|
| 43 | |
---|
| 44 | /** |
---|
| 45 | * This panel displays legends for a list of plots. If a given plot |
---|
| 46 | * has a custom colour defined then this panel allows the colour to |
---|
| 47 | * be changed. |
---|
| 48 | * |
---|
| 49 | * @author Mark Hall (mhall@cs.waikato.ac.nz) |
---|
| 50 | * @version $Revision: 4752 $ |
---|
| 51 | */ |
---|
| 52 | public class LegendPanel |
---|
| 53 | extends JScrollPane { |
---|
| 54 | |
---|
| 55 | /** for serialization */ |
---|
| 56 | private static final long serialVersionUID = -1262384440543001505L; |
---|
| 57 | |
---|
| 58 | /** the list of plot elements */ |
---|
| 59 | protected FastVector m_plots; |
---|
| 60 | |
---|
| 61 | /** the panel that contains the legend entries */ |
---|
| 62 | protected JPanel m_span=null; |
---|
| 63 | |
---|
| 64 | /** a list of components that need to be repainted when a colour is |
---|
| 65 | changed */ |
---|
| 66 | protected FastVector m_Repainters = new FastVector(); |
---|
| 67 | |
---|
| 68 | /** |
---|
| 69 | * Inner class for handling legend entries |
---|
| 70 | */ |
---|
| 71 | protected class LegendEntry |
---|
| 72 | extends JPanel { |
---|
| 73 | |
---|
| 74 | /** for serialization */ |
---|
| 75 | private static final long serialVersionUID = 3879990289042935670L; |
---|
| 76 | |
---|
| 77 | /** the data for this legend entry */ |
---|
| 78 | private PlotData2D m_plotData=null; |
---|
| 79 | |
---|
| 80 | /** the index (in the list of plots) of the data for this legend--- |
---|
| 81 | used to draw the correct shape for this data */ |
---|
| 82 | private int m_dataIndex; |
---|
| 83 | |
---|
| 84 | /** the text part of this legend */ |
---|
| 85 | private JLabel m_legendText; |
---|
| 86 | |
---|
| 87 | /** displays the point shape associated with this legend entry */ |
---|
| 88 | private JPanel m_pointShape; |
---|
| 89 | |
---|
| 90 | public LegendEntry(PlotData2D data, int dataIndex) { |
---|
| 91 | javax.swing.ToolTipManager.sharedInstance().setDismissDelay(5000); |
---|
| 92 | m_plotData = data; |
---|
| 93 | m_dataIndex = dataIndex; |
---|
| 94 | // this.setBackground(Color.black); |
---|
| 95 | /* this.setPreferredSize(new Dimension(0, 20)); |
---|
| 96 | this.setMinimumSize(new Dimension(0, 20)); */ |
---|
| 97 | |
---|
| 98 | if (m_plotData.m_useCustomColour) { |
---|
| 99 | this.addMouseListener(new MouseAdapter() { |
---|
| 100 | public void mouseClicked(MouseEvent e) { |
---|
| 101 | |
---|
| 102 | if ((e.getModifiers() & e.BUTTON1_MASK) == e.BUTTON1_MASK) { |
---|
| 103 | Color tmp = JColorChooser.showDialog |
---|
| 104 | (LegendPanel.this, "Select new Color", |
---|
| 105 | m_plotData.m_customColour); |
---|
| 106 | |
---|
| 107 | if (tmp != null) { |
---|
| 108 | m_plotData.m_customColour = tmp; |
---|
| 109 | m_legendText.setForeground(tmp); |
---|
| 110 | |
---|
| 111 | if (m_Repainters.size() > 0) { |
---|
| 112 | for (int i=0;i<m_Repainters.size();i++) { |
---|
| 113 | ((Component)(m_Repainters.elementAt(i))).repaint(); |
---|
| 114 | } |
---|
| 115 | } |
---|
| 116 | LegendPanel.this.repaint(); |
---|
| 117 | } |
---|
| 118 | } |
---|
| 119 | } |
---|
| 120 | }); |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | m_legendText = new JLabel(m_plotData.m_plotName); |
---|
| 124 | m_legendText.setToolTipText(m_plotData.getPlotNameHTML()); |
---|
| 125 | if (m_plotData.m_useCustomColour) { |
---|
| 126 | m_legendText.setForeground(m_plotData.m_customColour); |
---|
| 127 | } |
---|
| 128 | this.setLayout(new BorderLayout()); |
---|
| 129 | this.add(m_legendText, BorderLayout.CENTER); |
---|
| 130 | /* GridBagLayout gb = new GridBagLayout(); |
---|
| 131 | GridBagConstraints constraints = new GridBagConstraints(); |
---|
| 132 | constraints.fill = GridBagConstraints.HORIZONTAL; |
---|
| 133 | constraints.gridx=0;constraints.gridy=0;constraints.weightx=5; */ |
---|
| 134 | m_pointShape = new JPanel() { |
---|
| 135 | private static final long serialVersionUID = -7048435221580488238L; |
---|
| 136 | |
---|
| 137 | public void paintComponent(Graphics gx) { |
---|
| 138 | super.paintComponent(gx); |
---|
| 139 | if (!m_plotData.m_useCustomColour) { |
---|
| 140 | gx.setColor(Color.black); |
---|
| 141 | } else { |
---|
| 142 | gx.setColor(m_plotData.m_customColour); |
---|
| 143 | } |
---|
| 144 | Plot2D.drawDataPoint(10,10,3,m_dataIndex,gx); |
---|
| 145 | } |
---|
| 146 | }; |
---|
| 147 | // m_pointShape.setBackground(Color.black); |
---|
| 148 | m_pointShape.setPreferredSize(new Dimension(20, 20)); |
---|
| 149 | m_pointShape.setMinimumSize(new Dimension(20, 20)); |
---|
| 150 | this.add(m_pointShape, BorderLayout.WEST); |
---|
| 151 | } |
---|
| 152 | } |
---|
| 153 | |
---|
| 154 | /** |
---|
| 155 | * Constructor |
---|
| 156 | */ |
---|
| 157 | public LegendPanel() { |
---|
| 158 | this.setBackground(Color.blue); |
---|
| 159 | setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS); |
---|
| 160 | } |
---|
| 161 | |
---|
| 162 | /** |
---|
| 163 | * Set the list of plots to generate legend entries for |
---|
| 164 | * @param pl a list of plots |
---|
| 165 | */ |
---|
| 166 | public void setPlotList(FastVector pl) { |
---|
| 167 | m_plots = pl; |
---|
| 168 | updateLegends(); |
---|
| 169 | } |
---|
| 170 | |
---|
| 171 | /** |
---|
| 172 | * Adds a component that will need to be repainted if the user |
---|
| 173 | * changes the colour of a label. |
---|
| 174 | * @param c the component to be repainted |
---|
| 175 | */ |
---|
| 176 | public void addRepaintNotify(Component c) { |
---|
| 177 | m_Repainters.addElement(c); |
---|
| 178 | } |
---|
| 179 | |
---|
| 180 | /** |
---|
| 181 | * Redraw the panel with the legend entries |
---|
| 182 | */ |
---|
| 183 | private void updateLegends() { |
---|
| 184 | if (m_span == null) { |
---|
| 185 | m_span = new JPanel(); |
---|
| 186 | } |
---|
| 187 | |
---|
| 188 | JPanel padder = new JPanel(); |
---|
| 189 | JPanel padd2 = new JPanel(); |
---|
| 190 | |
---|
| 191 | m_span.setPreferredSize(new Dimension(m_span.getPreferredSize().width, |
---|
| 192 | (m_plots.size() + 1) * 20)); |
---|
| 193 | m_span.setMaximumSize(new Dimension(m_span.getPreferredSize().width, |
---|
| 194 | (m_plots.size() + 1) * 20)); |
---|
| 195 | |
---|
| 196 | LegendEntry tmp; |
---|
| 197 | |
---|
| 198 | GridBagLayout gb = new GridBagLayout(); |
---|
| 199 | GridBagLayout gb2 = new GridBagLayout(); |
---|
| 200 | GridBagConstraints constraints = new GridBagConstraints(); |
---|
| 201 | |
---|
| 202 | m_span.removeAll(); |
---|
| 203 | |
---|
| 204 | padder.setLayout(gb); |
---|
| 205 | m_span.setLayout(gb2); |
---|
| 206 | constraints.anchor = GridBagConstraints.CENTER; |
---|
| 207 | constraints.gridx=0;constraints.gridy=0;constraints.weightx=5; |
---|
| 208 | constraints.fill = GridBagConstraints.HORIZONTAL; |
---|
| 209 | constraints.gridwidth=1;constraints.gridheight=1; |
---|
| 210 | constraints.insets = new Insets(0, 0, 0, 0); |
---|
| 211 | padder.add(m_span, constraints); |
---|
| 212 | |
---|
| 213 | constraints.gridx=0;constraints.gridy=1;constraints.weightx=5; |
---|
| 214 | constraints.fill = GridBagConstraints.BOTH; |
---|
| 215 | constraints.gridwidth=1;constraints.gridheight=1;constraints.weighty=5; |
---|
| 216 | constraints.insets = new Insets(0, 0, 0, 0); |
---|
| 217 | padder.add(padd2, constraints); |
---|
| 218 | |
---|
| 219 | constraints.weighty=0; |
---|
| 220 | setViewportView(padder); |
---|
| 221 | |
---|
| 222 | constraints.anchor = GridBagConstraints.CENTER; |
---|
| 223 | constraints.gridx=0;constraints.gridy=0;constraints.weightx=5; |
---|
| 224 | constraints.fill = GridBagConstraints.HORIZONTAL; |
---|
| 225 | constraints.gridwidth=1;constraints.gridheight=1;constraints.weighty=5; |
---|
| 226 | constraints.insets = new Insets(2,4,2,4); |
---|
| 227 | //int numLines = ((PlotData2D)m_plots.elementAt(0)).getPlotName().split("<br>").length; |
---|
| 228 | for (int i=0;i<m_plots.size();i++) { |
---|
| 229 | tmp = new LegendEntry((PlotData2D)m_plots.elementAt(i),i); |
---|
| 230 | constraints.gridy = i; |
---|
| 231 | /* constraints.gridheight = 1; |
---|
| 232 | if (numLines > 0) { |
---|
| 233 | constraints.gridheight = (numLines + 2); |
---|
| 234 | } */ |
---|
| 235 | m_span.add(tmp, constraints); |
---|
| 236 | } |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | /** |
---|
| 240 | * Main method for testing this class |
---|
| 241 | * @param args a list of arff files |
---|
| 242 | */ |
---|
| 243 | public static void main(String [] args) { |
---|
| 244 | try { |
---|
| 245 | if (args.length < 1) { |
---|
| 246 | System.err.println("Usage : weka.gui.visualize.LegendPanel " |
---|
| 247 | +"<dataset> [dataset2], [dataset3],..."); |
---|
| 248 | System.exit(1); |
---|
| 249 | } |
---|
| 250 | |
---|
| 251 | final javax.swing.JFrame jf = |
---|
| 252 | new javax.swing.JFrame("Weka Explorer: Legend"); |
---|
| 253 | jf.setSize(100,100); |
---|
| 254 | jf.getContentPane().setLayout(new BorderLayout()); |
---|
| 255 | final LegendPanel p2 = new LegendPanel(); |
---|
| 256 | jf.getContentPane().add(p2, BorderLayout.CENTER); |
---|
| 257 | jf.addWindowListener(new java.awt.event.WindowAdapter() { |
---|
| 258 | public void windowClosing(java.awt.event.WindowEvent e) { |
---|
| 259 | jf.dispose(); |
---|
| 260 | System.exit(0); |
---|
| 261 | } |
---|
| 262 | }); |
---|
| 263 | |
---|
| 264 | FastVector plotList = new FastVector(); |
---|
| 265 | for (int j=0;j<args.length;j++) { |
---|
| 266 | System.err.println("Loading instances from " + args[j]); |
---|
| 267 | java.io.Reader r = new java.io.BufferedReader( |
---|
| 268 | new java.io.FileReader(args[j])); |
---|
| 269 | Instances i = new Instances(r); |
---|
| 270 | PlotData2D tmp = new PlotData2D(i); |
---|
| 271 | if (j != 1) { |
---|
| 272 | tmp.m_useCustomColour = true; |
---|
| 273 | tmp.m_customColour = Color.red; |
---|
| 274 | } |
---|
| 275 | tmp.setPlotName(i.relationName()); |
---|
| 276 | plotList.addElement(tmp); |
---|
| 277 | } |
---|
| 278 | |
---|
| 279 | p2.setPlotList(plotList); |
---|
| 280 | jf.setVisible(true); |
---|
| 281 | } catch (Exception ex) { |
---|
| 282 | System.err.println(ex.getMessage()); |
---|
| 283 | ex.printStackTrace(); |
---|
| 284 | } |
---|
| 285 | } |
---|
| 286 | } |
---|