SwingHack Free ebook download Free ebook download


3 months ago
Full text

1.1. Hacks 112: Introduction

  By adjusting the returned size to be a bit bigger, layout controls using this component will give the label the extra room it needs: public Dimension getPreferredSize() {String text = getText();FontMetrics fm = this.getFontMetrics(getFont()); int w = fm.stringWidth(text); This implementation of getPreferredSize() calculates the size based on the font metrics of the currently set text. You've got to have pretty images, a component to paint them on, and then some logic to handle the different parts of the date, including what day of the week starts off the current month.

1.5.1. Create the Images

  I created three images in Photoshop: one for the background, one for each day, and one for the current day. highlight.png for the current dayI could have separated the day names and the title, but since they don't change, it was simpler to make them part of the image.

1.5.2. A Component to Paint

  The easiest way to create a custom component with fancy drawing is to start off with a JPanel and override the paintComponent() method, as shown in Example 1-9 . Override thepaintComponent() method to turn on anti-aliasing, draw the background, and then draw the month and year for the current date.

1.5.3. Draw the Days of the Month

  After setting up a standard JTextArea , the code creates a new ScrollPaneWatermark viewport and loads up the images (clouds.jpg is a tileable image of pale, fluffy clouds, and flyingsaucer.jpg is a small image of a flying saucer with atranslucent drop shadow that will blend nicely over the text). Scheduling the AnimationSince the pane was added as a ChangeListener to itself, the stateChanged ( ) method will be called whenever the user ChangeListener stateChangedSince the pane was added as a to itself, the ( ) method will be called whenever the user switches tabs.

1.9.3. Drawing the Animation

  By drawing the component to a bitmap, blurring that bitmap, and then drawing the bitmap in the place of the component, you caneffectively have a blurred component without disturbing the rest of the Swing painting routines. By passing in instead of the g variable, the button will be drawn entirely to the image buffer, thus enabling the blurring: float[] my_kernel = {0.10f, 0.10f, 0.10f,0.10f, 0.20f, 0.10f,0.10f, 0.10f, 0.10f };ConvolveOp op = new ConvolveOp(new Kernel(3,3, my_kernel));Image img = op.filter(buf,null);g.drawImage(img,0,0,null); Blurring is a complex operation where each pixel is averaged with the pixels next to it to create a new pixel.

1.11.1. Adding a Color Selection Panel

  The actual painting code is very simple: set the color to black, translate the graphics origin to be relative to the x and y passed in, draw the shadow, and translate back. Overriding the paint() method of the JMenu wouldn't do any good because the JMenu doesn't draw what we think of as a menua list of menu items that pop up when you click on the menu's title.

1.13.1. Make the Custom Menu Item

  The puts all of the menu items inside of a , which is placed inside of a , and then the whole deal is put in a layered pane at the top of the frame. Normally, Swing will use lightweight menus, but if the menu has to be drawn outside of the framewhich can happen if you have a small window or a really large menuthen it will switch to heavyweight menus automaticallyand nothing can switch it back until the application restarts.

1.13.4. Future Ideas

  Java2D gives you the power to create a wide variety of graphical hacks. As an extension of thistechnique, you could try blurring the components underneath the menu or create a properly smoothed drop shadow.

2.1. Hacks 1320: Introduction

  To implement this functionality in a JList , you basically just have to implement the full set of AWT drag-and-drop interfaces because the list will be both the source of the drag and the target of the drop. When the list is repainted, which will happen every time the mouse moves over theJList during a drag, the cell that you're dragging over will draw a line at the top of itself to indicate that the drop will put the dragged item before this one.

2.8.1. Building a Generic Renderer The default JList cell renderer will just call toString () on the objects in the list and draw the resulting string to the screen

  This string is the name of the method to call on the list value objects. If the reflection fails, then it will set the text using ( ) on the list item as a backup, which is what the standard renderer would do.

2.8.2. Putting It All Together

  Instead of creating a custom renderer or wrapping the entries in objects with a custom toString ( ) method, you could use the GenericListCellRenderer with getTitle ( ) to automatically call the getTitle () methodon the entry objectsno new subclasses or extra code. uses the index to get the display values and getSize() uses the size of the Map itself.actionPerformed() is different from the List version and calls buildIndex() before fireUpdate() .

3.1. Hacks 2127: Introduction

  However, the JTable may be used too muchit's easy to throw an Object[][] at the constructor and get afull-blown GUI table, and some developers don't question the wisdom of this sort of coding. In this case, the count column has lots of pixels to spare; youjust need to reallocate this extra space to the URL column.

3.2.1. Resetting Column Widths

  As with components that defer to layout managers, the right property to reset is the preferred widthlet the column tell the JTable how wide it would like to be, but let the JTable make the final decision based on the information available to it(after all, there could be other columns contending for space, there might not be enough space for all the columns'preferred size, etc.). If you resize the JFrame , the columns will gain and lose space proportionally, so the URL column will always have much more space than the count column, making it more likely the table will be well-suited to further contents you might add.

3.2.2. Accounting for Header Cells

  There's a problem with the new weighting of the column widths: since the one-digit contents of the count column are so narrow, the count column header has been crushed to the point where Swing needs to show it with ellipses. If you really wanted to keep headercells intact, you could alter the previous code to set the TableColumn's minimum width to the preferred width of the header cell, assuming the header isn't much wider than the content.

3.2.3. Hacking the Hack

  "But," you might be saying, "what if I don't have my table data in advance?" If you have some idea of what the data is probably going to be like, you could create your table, add this "prototype" data as a row, size the columns, and thenremove the prototype…all before ever making the table visible. Next in the source, you'll find a series of methods that involve the contents of the model:getColumnCount() getColumnName()getrowCount() getValueAt()isCellEditable() setValueAt() All of these methods delegate to the wrapped model, with the caveat that any that work with rows look up the mapped row from the sortedIndicies array, as seen in Example 3-6 .

3.5.1. Building Connectivity

  With these two queries done, you have everything you need to support the abstract methods of AbstractTableModel : getRowCount() is the length of the contents array that you create.getColumnCount()is 0 if you have no contents, or the length of the first item in the contents array (which is itself an array because contents is a two-dimensional array).getValueAt() is the value at contents[row][col] . A caller might decide to use a TableCellRenderer that applies a Format class to all Doubles in the table to display them only to a certain number of decimal points, or to render Dates withrelative terms like "Today" and "25 hours ago." Strongly typing the data in your model will help with that.

3.5.2. Testing Things Out

  The model gets the Connection and the name of this table and loads the data from the database. In fact, because it returns the name of the table you've created, you could create many different tables in your database andtest out how the model handles them.

3.6.1. Dealing with Formatting

  The code loops through the column names and prints them to the writer, following each column name with\t \na , which represents the tab character, and finally an (the Unix newline character, which will work fine on both Mac OS X and Windows) at the end of the line. This method clears the searching state by making a one-to-one mapping of the inner table model to this table model: private void clearSearchingState(){ Now, you need to change the row reference methods to indirect through the row to model index before hitting the inner table model: public int getRowCount() { return (tableModel == null) ?

3.7.4. Indexing

  You'll also need an that helps communicate between data and the index, as well as an IndexWriter that actually writes to the index: directory = new RAMDirectory(); analyzer = new WhitespaceAnalyzer();IndexWriter writer = new IndexWriter(directory, analyzer, true); For the purposes of indexing, think of every row as a document and every column as a word or a set of words (called aField in Lucene-speak) for that document. Now, loop through the table model's rows, creating a new Document for eachrow and add Fields per column: for (int row=0; row < tableModel.getRowCount(); row++){Document document = new Document();//add fields writer.addDocument(document);} First, add a field with the row index in the inner table model.

3.7.5. Searching

  First, you have to hit the Lucene index with a search string. This will give you a list of rows in the inner table model that match the search. Getting results from the index

  Start by clearing the row-to-model index to get rid of the previous results: rowToModelIndex.clear(); The Hits object contains a number of Documents , just like the ones you put into the index. So, now you can iterate through the Documents and get the row number fromthe field value: for (int t=0; t<hits.length(); t++){Document document = hits.doc(t);Field field = document.getField(ROW_NUMBER);Integer rowNumber = new Integer(field.stringValue());} } The last step is to add an Integer to the row-to-model index with the row number retrieved from the document. Listen to inner table updates

  The simple solution is to add a TableModelListener to the inner table to rebuild the index, and then rerun thesearch against the new index. You could narrow down the area of the table that changed to fire more accurate events to the table. Clear search results for blank search

  The easiest way to do this is to check for an empty string in the search method. If they search with an empty string, clear the search and rerun themethod that indexes all of the inner table model without a search: public void search(String searchString){ if (searchString == null || searchString.equals("")){clearSearchingState(); fireTableDataChanged();return;}//rest of search method} If you wanted to hack further, you could make this and other small functions like it each separate decorators.

3.7.8. Wrapping Up

  The problem is that the JTree isn't really a container, so from the Swing programmer's point of view, you see the tree's visual representation, but not the nodes within it. The payoff is that making a single treereorderable will also get you most of the way to making it a good drag-and-drop participant with the rest of your application, since supporting drag-and-drop within the JTRee requires you to make the tree a drag source and a droptarget.

3.8.1. The Code

  JTree with drag-and-drop reordering [Hack #17]In fact, the code for this hack started as a straight port of the reorderable JList hack , with obvious changes for the different helper classes ( treeCellRenderer instead of ListCellRenderer ) and different handling of the model,since tree models are hierarchical. To recap what needs to be done: The tree needs to implement the DragGestureListener (to start a drag), the DropTargetListener (to handle the drop),and the DragSourceListener (only to get the end-of-drop callback).

3.8.2. Running the Code The main method, shown in Example 3-17 , builds a reorderable tree and puts it in a JFrame

  Dragging a node within a JTreeBecause the drop is occurring over a leaf, the custom rendering shows a line on top of the "Michael" node, meaning that "Chris" will be inserted before "Michael". In this case, the drag is over the "Set 1" branch, which causes it to be drawn with a box around it, suggesting that the dropwill be "into" the branch.

Chapter 4. File Choosers

4.1. Hacks 2832: Introduction

  This is Swing after all,and that means there are all sorts of places that you can hack in and embellish functionality to give the user more power, or to make a component smarter about the contents it displays. Add a Right-Click Context Menu to the JFileChooser Improve the native platform fidelity of the by adding a contextual menu that lets the user create JFileChooser new folders and delete files.

4.2.1. The Problem

  For the most part, Swing is quite extensible, but often only in ways that the Swing team thought of beforehand. TheJFileChooser has ways to change the rendering of file icons, filtering the file list, adding components, and changing thetext.

Chapter 8 has a hack for adding pop-up menu support to any frame; see "Create a Global Right-Click" [Hack #57] . By

  It is important to set the view before the showOpenDialog () because file chooserscannot be changed after they have been shown on screen: public class DisplayShortcutTest { public static void main(String[] args) throws Exception {JFileChooser chooser = new JFileChooser(); chooser.setFileView(new ShortcutFileView());chooser.showOpenDialog(null);}} This program changes the look of shortcuts to look like folders and be clickable, but they still don't have the link icon. You can do this by asking for the icon of a known folder, in this case C:\windows: // get the standard icon for a folderFile tmp = new File("C:\\windows");Icon folder = def.getIcon(tmp); int w = folder.getIconWidth();int h = folder.getIconHeight(); Once you have the icon, you can build a new image to draw it on, and then overlay the link graphic: // create a buffered image the same size as the iconImage img = new BufferedImage(w,h,BufferedImage.

Dokumen baru

Aktifitas terkini

Download (924 Halaman)


Qmail Ebook Free Download Ebook Free Download Practical Mod Free Ebook Download Free Ebook Download Netcat Starter Free Ebook Download Free Ebook Download Pro Wicket Free Ebook Download Free Ebook Download Ubuntu Hacks Free Ebook Download Free Ebook Download Jquery Hotshot Free Ebook Download Free Ebook Download Core Data Ebook Free Download Free Ebook Download Pdf Hacks Free Ebook Download Free Ebook Download Dm Yale 1999 Ebook Free Download Ebook Free Download Sybex Groun Java Free Ebook Download Free Ebook Download
Show more