Back to index

wims  3.65+svn20090927
TabPanel.java
Go to the documentation of this file.
00001 /*
00002  * @(#)TabPanel.java
00003  * 
00004  * $Id: TabPanel.java,v 1.5 2001/05/27 22:29:49 huaz Exp $
00005  * 
00006  * Created Novenmber 27, 2000, 11:27 PM
00007 */
00008 package SharpTools;
00009 import java.awt.*;
00010 import java.awt.event.*;
00011 import javax.swing.*;
00012 import java.util.*;
00021 public class TabPanel extends JPanel {
00022 
00023     private Histogram owner;
00024     private SharpTableModel model;
00025     private JTabbedPane tab;
00026     private HistoPanel histo;
00027     // values
00028     private CellRange range;
00029     private Float startvalue, endvalue, bucketvalue,
00030        xmin, xmax, ymin, ymax, xunit, yunit;
00031     private boolean bypercentage = true;    
00032 
00041     TabPanel(SharpTableModel tableModel, CellRange range,
00042             Histogram frame, JTabbedPane pane) {
00043        super();
00044        this.owner = frame;
00045        this.model = tableModel;
00046        this.tab = pane;
00047        this.range = range;
00048        
00049        // set layout - tedious..
00050        setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
00051        setLayout(new BorderLayout());
00052 
00053        // add the HistoPanel - our canvas
00054        histo = new HistoPanel();
00055        histo.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
00056        add(histo, BorderLayout.CENTER);   
00057 
00058        // buttons
00059        JPanel south = new JPanel();
00060        south.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
00061        south.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 0));
00062 
00063        // Remove button
00064        final ImageIcon noIcon=new ImageIcon(getClass().getResource("/images/no.gif"));
00065        JButton closeButton = new JButton(SharpTools.translation.getProperty("Remove"), noIcon);
00066 //     JButton closeButton = new JButton("Remove", SharpTools.getImageIcon("no.gif"));
00067        closeButton.setMnemonic(KeyEvent.VK_R);
00068        closeButton.addActionListener(new ActionListener() {
00069               public void actionPerformed(ActionEvent evt) {
00070                   // remove the current tab
00071                   tab.remove(tab.getSelectedComponent());
00072                   
00073                   // if there is no tab left, close the window
00074                   if (tab.getTabCount() == 0) {
00075                      owner.hide();
00076                   }
00077               }
00078            });
00079 
00080        // Options button
00081        final ImageIcon optionsIcon=new ImageIcon(getClass().getResource("/images/options.gif"));
00082        JButton optionButton = new JButton(SharpTools.translation.getProperty("Options"), optionsIcon);   
00083        //JButton optionButton = new JButton("Options...", SharpTools.getImageIcon("options.gif"));       
00084        optionButton.setMnemonic(KeyEvent.VK_O);
00085        optionButton.addActionListener(new ActionListener() {
00086               public void actionPerformed(ActionEvent evt) {
00087                   getOptions(false);                 
00088               }
00089            });
00090 
00091        // Update button
00092        final ImageIcon refreshIcon=new ImageIcon(getClass().getResource("/images/refresh.gif"));
00093        JButton updateButton = new JButton (SharpTools.translation.getProperty("Update"), refreshIcon);
00094        //JButton updateButton = new JButton ("Update", SharpTools.getImageIcon("refresh.gif"));
00095 
00096        updateButton.setMnemonic(KeyEvent.VK_U);
00097        updateButton.addActionListener(new ActionListener() {
00098               public void actionPerformed(ActionEvent evt) {
00099                   updateData();
00100                   histo.paintImmediately(0, 0, histo.getWidth(),
00101                                       histo.getHeight());
00102               }
00103            });
00104        
00105        south.add(updateButton);
00106        south.add(optionButton);
00107        south.add(closeButton);
00108        
00109        add(south, BorderLayout.SOUTH);
00110     }    
00111 
00117     void getOptions(boolean firstTime) {
00118 
00119        HistoDialog option = new HistoDialog(owner);
00120        option.pack();
00121        option.setLocationRelativeTo(owner);
00122 
00123        // title textfield
00124        option.setTitleField(tab.getTitleAt(tab.getSelectedIndex()));
00125        
00126        if (firstTime) {
00127            // set initial values
00128            option.setCellRange(range);
00129 
00130            float[] minmax = TabPanel.getValueMinMax(model, range);
00131            int min = (int)minmax[0];
00132            int max = (int)minmax[1];
00133 
00134            startvalue = new Float(min);       
00135            endvalue = new Float(max);         
00136 
00137            // estimate a reasonable bucket size
00138            int power = 0;
00139            if (max>min)
00140               power = (int)((Math.log(max-min)/Math.log(10)));
00141            if (power<0)
00142               power--;
00143            
00144            bucketvalue = new Float(Math.pow(10, power));
00145            xunit = bucketvalue;
00146 
00147            xmin = new Float(min);
00148            xmax = new Float(max);
00149            
00150            ymin = new Float(0);
00151            ymax = new Float(100);
00152            yunit = new Float(10);
00153 
00154        }
00155 
00156        // initialize all the fields
00157        option.setCellRange(range);
00158        option.setStartValue(startvalue);
00159        option.setEndValue(endvalue);
00160        option.setBucket(bucketvalue);
00161        option.setXMin(xmin);
00162        option.setXMax(xmax);
00163        option.setXUnit(xunit);
00164        option.setYMin(ymin);
00165        option.setYMax(ymax);
00166        option.setYUnit(yunit);
00167        option.setByPercentage(bypercentage);
00168 
00169        // show the dialog
00170        option.setVisible(true);
00171 
00172        if (!option.isCancelled()) {
00173 
00174            // save data
00175            tab.setTitleAt(tab.getSelectedIndex(),
00176                         option.getTitleField());
00177            range = option.getCellRange();
00178            startvalue = option.getStartValue();
00179            endvalue = option.getEndValue();
00180            bucketvalue = option.getBucket();
00181            xmin = option.getXMin();
00182            xmax = option.getXMax();
00183            ymin = option.getYMin();
00184            ymax = option.getYMax();
00185            xunit = option.getXUnit();
00186            yunit = option.getYUnit();
00187            bypercentage = option.getByPercentage();
00188 
00189            // do an update to repaint the chart
00190            update();
00191        }
00192     }
00193     
00201     static float[] getValueMinMax(SharpTableModel model, CellRange range) {
00202        // value[0] is min, value[1] is max
00203        float[] values = { Float.MAX_VALUE, Float.MIN_VALUE };
00204        float v;
00205        for (int i = range.getStartRow(); i <= range.getEndRow(); i++)
00206            for (int j = range.getStartCol(); j <= range.getEndCol(); j++) {
00207               try {
00208                   v = model.getNumericValueAt(i, j).floatValue();
00209               }
00210               catch (ParserException e) {
00211                   v= 0;
00212               }
00213 
00214               values[0] = Math.min(values[0], v);
00215               values[1] = Math.max(values[1], v);
00216            }
00217 
00218        return values;
00219     }
00220 
00226     public void update() {
00227 
00228        float start = startvalue.floatValue();
00229        float end = endvalue.floatValue();
00230        float bucket = bucketvalue.floatValue();
00231        float nb = (end-start)/bucket;
00232        int nbars = (int)nb;
00233        if (nbars > (int)nbars)
00234            nbars++;
00235 
00236        // values below and above
00237        nbars += 2;
00238 
00239        float[] data = new float[nbars];
00240        histo.setData(data);
00241 
00242        updateData();
00243        
00244        histo.setStartEndPoints(start, end, bucket);
00245        histo.setXYAxis(xmin.floatValue(),
00246                      xmax.floatValue(),
00247                      xunit.floatValue(),
00248                      ymin.floatValue(),
00249                      ymax.floatValue(),
00250                      yunit.floatValue());
00251 
00252        histo.setByPercentage(bypercentage);
00253        histo.paintImmediately(0, 0, histo.getWidth(), histo.getHeight());
00254        
00255     }
00256 
00263     private void updateData() {
00264 
00265        float start = startvalue.floatValue();
00266        float end = endvalue.floatValue();
00267        float bucket = bucketvalue.floatValue();
00268        float[] data = histo.getData();
00269        
00270        for (int k = 0; k < data.length; k++)
00271            data[k] = 0;
00272        
00273        // two more buckets below start or above end
00274        //     float scale = end-start+2;
00275 
00276        for (int i = range.getStartRow(); i <= range.getEndRow(); i++) {
00277             for (int j = range.getStartCol(); j <= range.getEndCol(); j++) {
00278               
00279               float value = 0;
00280 
00281               try {
00282                   value = model.getNumericValueAt(i, j).floatValue();
00283               }
00284               catch (Exception e) {
00285               }
00286               
00287               if (value < start)
00288                   data[0]++;
00289               else if (value > end)
00290                   data[data.length-1]++;
00291               else {
00292                   int index = (int)((value-start)/bucket)+1;
00293                   data[index]++;
00294               }
00295            }
00296        }
00297 
00298        if (bypercentage) {
00299            int nums = range.getWidth()*range.getHeight();
00300            for (int k = 0; k < data.length; k++)
00301               data[k] = data[k]*100/nums;
00302        }
00303        // histo.setData(data); - dont need it since we've modified in-place
00304     }
00305 }
00306 
00323 class HistoPanel extends JPanel /*implements ComponentListener*/ {    
00324 
00325     private float[] bars; // distribution
00326     private float start, end, bucket;
00327     private float xmin, xmax, xunit;
00328     private float ymin, ymax, yunit;
00329     private float xscale, yscale; // xmax-xmin and ymax-ymin
00330     
00331     private int xsize, ysize;
00332     private int xborder = 50;
00333     private int yborder = 40;
00334     private boolean bypercentage;
00335     //    private int maxdigits;
00336 
00337     public void setStartEndPoints(float start, float end, float bucket) {
00338        this.start = start;
00339        this.end = end;
00340        this.bucket = bucket;
00341     }
00342 
00343     public void setXYAxis(float xmin, float xmax, float xunit,
00344                        float ymin, float ymax, float yunit) {
00345        this.xmin = xmin;
00346        this.xmax = xmax;
00347        this.xunit = xunit;
00348        this.ymin = ymin;
00349        this.ymax = ymax;
00350        this.yunit = yunit;
00351 
00352        xscale = xmax-xmin;
00353        yscale = ymax-ymin;
00354 
00355        // calculate optimized xborder
00356        int len1 = String.valueOf(ymin).length();
00357        int len2 = String.valueOf(ymax).length();
00358        int len3 = String.valueOf(yunit).length();
00359 
00360        int maxdigits = Math.max(Math.max(len1, len2), len3);
00361        xborder = maxdigits*getGraphics().getFontMetrics().charWidth('0')+10;
00362        
00363     }
00364 
00365     public void setByPercentage(boolean bypercentage) {
00366        this.bypercentage = bypercentage;
00367     }
00368     
00369     public void setData(float[] data) {
00370        bars = data;
00371     }
00372 
00373     public float[] getData() {
00374        return bars;
00375     }
00376     
00382     public void paintComponent(Graphics g) {
00383        super.paintComponent(g);    
00384 
00385        if (bars == null)
00386            return;
00387        
00388        xsize = getXSize();
00389        ysize = getYSize();
00390 
00391        // draw x axise
00392        if (xsize < 0 || ysize < 0)
00393            return;
00394 
00395        float xratio = xscale/xsize;
00396        float yratio = yscale/ysize; // xscale/xsize; yscale/ysize
00397        
00398        // x axis
00399        drawLine(g, 0, 0, xsize+20, 0);
00400        // y xais
00401        drawLine(g, 0, 0, 0, ysize+20);
00402 
00403        if (bypercentage)
00404            cString(g, "(%)", 0, ysize+30);
00405 
00406        // draw x ticks
00407        for (float x = xmin; x <= xmax; x+=xunit) {
00408            int xcoor = (int)((x-xmin)/xratio);
00409            drawLine(g, xcoor, +3, xcoor, -3);
00410            cString(g, String.valueOf(x), xcoor, -20);
00411        }
00412 
00413        // draw y ticks
00414        for (float y = ymin; y <= ymax; y+=yunit) {
00415            int ycoor = (int)((y-ymin)/yratio);
00416            drawLine(g, -3, ycoor, +3, ycoor);
00417            rString(g, String.valueOf(y), -5, ycoor);
00418        }
00419        
00420        // draw bars!
00421        // int barwidth = (int)(bucket/xratio);
00422        for (int i = 0; i < bars.length; i++) {
00423            // for (float x = start-bucket; x < end+bucket; x+=bucket) {
00424            float x = start+(i-1)*bucket;
00425            int ycoor = (int)((bars[i]-ymin)/yratio);
00426            
00427            int xcoor1 = (int)((x-xmin)/xratio);
00428            int xcoor2 = (int)((x+bucket-xmin)/xratio);
00429            
00430 
00431            // must be in range
00432            xcoor1 = Math.max(xcoor1, 0);
00433            xcoor2 = Math.min(xcoor2, xsize);
00434 
00435            if (i == 0)
00436               xcoor1 = 0;
00437 
00438            if (i == bars.length-1)
00439               xcoor2 = xsize;
00440            
00441            if (xcoor1 >= xcoor2)
00442               continue;
00443 
00444            // draw the bar
00445            drawLine(g, xcoor1, 0, xcoor1, ycoor);
00446            
00447            drawLine(g, xcoor2, 0, xcoor2, ycoor);
00448            
00449            drawLine(g, xcoor1, ycoor, xcoor2, ycoor);
00450 
00451        }
00452        
00453     }
00454 
00455     private int getXSize() {
00456        return getWidth()-2*xborder;
00457     }
00458     
00459     private int getYSize() {
00460        return getHeight()-2*yborder;
00461     }
00462 
00463     // draw a line between virtual coordinates (x1, y1) and (x2, y2)
00464     // borders are taken into account and Y axis is upwards.
00465     private void drawLine(Graphics g, int x1, int y1, int x2, int y2) {
00466 
00467        // draw axis
00468        g.drawLine(x1+xborder, ysize-y1+yborder,
00469                  x2+xborder, ysize-y2+yborder);
00470     }
00471 
00472     // draw a string at virtual coordinate (x, y)
00473     // borders are taken into account and Y axis are up.
00474     private void drawString(Graphics g, String s, int x, int y) {
00475 
00476        // draw axis
00477        g.drawString(s, x+xborder, ysize-y+yborder);
00478     }
00479     
00480     
00481     // do some internal coordinate SharpTools.translation
00482     
00483     // coordinate SharpTools.translation for X (to virtual coordinate)
00484     private int getx(int x) {
00485        return x+xborder;
00486     }
00487     
00488     // coordinate SharpTools.translation for Y (to virtual coordinate)
00489     private int gety(int y) {
00490        return ysize-y+yborder;
00491     }
00492 
00493     // display a string by center alignment
00494     private void cString(Graphics g1, String s, int i, int j) {
00495         int k = g1.getFontMetrics().stringWidth(s);
00496         drawString(g1, s, i - k / 2, j);
00497     }
00498 
00499     // display a string by right alignment
00500     private void rString(Graphics g1, String s, int i, int j) {
00501         int k = g1.getFontMetrics().stringWidth(s);
00502         drawString(g1, s, i - k, j);
00503     }
00504 
00505 }
00506