출처

SWT 는 Date Time Widget 이 제공되기 때문에 화면 구성하는데 편하지만.. 스윙에서는 제작된 컴포넌트를 찾아서 사용하거나.. 직접 제작해야 한다. 여기서 문제는 누가 달력을 일일이 그려주느냐고.. 제작된 쓸만한 넘들은 상용제품이라 돈을 지불해야 한다는 것이다.

확실히 상용제품보다 사용하는 면이나 비쥬얼에서 딸리지만 그래도 가장 쓸만한 넘을 하나 추천한다.

JCalendar 의 사용법을 올리면 좋겠지만.. 위 사이트에서 소스까지 공개하기 때문에 데모를 따라가다 보면 적당히 가지고 놀수는 있을듯 싶다.


ps.

단기간에 뚝딱 만들고 싶으면 NetBeasn 를 이용하여 스윙으로 개발하는게 좋겠지만.. 개인적으로 추천은 Eclipse + SWT 를 추천한다. 뭐 SWT로만 부족하다면 거기에 Swing 추가해서 개발하는 것도 좋을거 같다.


'java > swing' 카테고리의 다른 글

[swing] - TableModel 만들기  (0) 2010.06.30
[swing] - Tree Cell Background&Select Background Color 변경  (0) 2010.06.30
[swing] - Image Tooltip 만들기  (0) 2010.06.30
[swing] - Title Border 만들기  (0) 2010.06.29
[swing] - TreeTable sample  (2) 2010.06.29
Posted by 짱가쟁이
참조

JTabbedPane Class 를 확장하여 Tooltip을 해당 tab의 이미지로 보여주는 일을 수행한다. 복잡한 코드가 필요하지도 않고 유용한 정보인듯 싶어 참고로 올린다.

<실행화면>

위 사이트에 올려놓은 소스를 Netbeans 의 Palette 에 추가해서 테스를 진행했다.

 Palette 에 추가해서 정상적으로 그림은 그려졌지만 이상하게 Tooltip이 이미지로 보이지 않음.

 마법사를 이용하여 JFrame Form 으로 클래스를 생성시 "Generated Code" 부분에서 문제가 있을거 같아 찬찬히 찾아보니.. "JThumbnailTabbedPane.java" 에서 add() 만 구현했기 때문에 발생된 문제였음.

실제로 NetBeans 에서 생성된 코드에서는 addTab() 를 사용함.




Generated Code

// <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jThumbnailTabbedPane1 = new swing_sample.tooltiptab.JThumbnailTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jScrollPane1.setViewportView(jTree1);

        jThumbnailTabbedPane1.addTab("tab1", jScrollPane1);

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane2.setViewportView(jTable1);

        jThumbnailTabbedPane1.addTab("tab2", jScrollPane2);

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jThumbnailTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE)
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jThumbnailTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 487, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>


NetBeans 의 "Generated Code" 부분을 수정하면 좋겠지만.. 수정하는 방법을 못찾음..

다운로드 받은 JThumbnailTabbedPane.java 에 "addTab()" 추가해서 문제를 해결함.

책 제목은 생각나지 않지만.. "사악한 마법사" 를 조심하라는 말이 불현듯 떠올랐다.

마법사를 이용하여 코드를 생성할때 생성된 코드를 제대로 이해하지 않고 사용하면 지금과 같은 문제가 발생한다는 말이였다. 아무리 책을 많이 읽고 "흠.. 그렇지" 라고 동의를 했더라도, 이렇듯 직접 문제에 직면하지 않으면 아무런 도움이 안되는듯 싶다. (표현이 너무 강한듯..)

 

Posted by 짱가쟁이
출처

- Border 에 타이틀을 넣어준다.

<실행화면>


GradientTitleBorder.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package swing_sample.customborder;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import javax.swing.UIManager;
import javax.swing.border.Border;

/**
 *
 * @author Administrator
 */
public class GradientTitleBorder implements Border {

    private String title;

    private int titleHeight;

    private Insets insets = new Insets(titleHeight, 0, 0, 0);

    private Color primaryColor;

    private Color secondaryColor;

    private Color fontColor;

    private Color shadowColor;

    private int indent = 5;

    private Font titleFont;

    /**
    * Constructtor that assumes a title height.
    *
    * @param title - string to display
    * @param primaryColor - first color of gradient
    * @param secondaryColor - second color of gradient (lower)
    * @param fontColor - color for the font
    */
    public GradientTitleBorder(String title, Color primaryColor, Color secondaryColor, Color fontColor) {
        this(title, primaryColor, secondaryColor, fontColor, 30);
    }

    /**
     * Full option constructor
     *
     * @param title - string to display
     * @param primaryColor - first color of gradient
     * @param secondaryColor - second color of gradient (lower)
     * @param fontColor - color for the font
     * @param titleHeight - height of the title bar
     */
    public GradientTitleBorder(String title, Color primaryColor, Color secondaryColor, Color fontColor, int titleHeight) {
        this.title = title;
        this.titleHeight = titleHeight;
        this.insets = new Insets(titleHeight, 2, 2, 2);
        this.primaryColor = primaryColor;
        this.shadowColor = primaryColor.darker();
        this.secondaryColor = secondaryColor;
        this.fontColor = fontColor;
        this.titleFont = UIManager.getFont("TitledBorder.font").deriveFont(Font.BOLD);
    }

    /**
     * Creates a GradientTitleBorder with default values.
     * @param title
     */
    public GradientTitleBorder(String title) {
        this(title, Color.BLACK, Color.GRAY, Color.WHITE, 30);
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

        GradientPaint gp = new GradientPaint(x, y, primaryColor, x, y + titleHeight, secondaryColor);
        g2d.setPaint(gp);
        g2d.fillRect(x, y, width, titleHeight);

        g2d.setColor(shadowColor);
        g2d.drawRect(x, y - 1, width - 1, titleHeight);

        g2d.setFont(titleFont);

        g2d.setColor(shadowColor);
        int titleOffset = (titleHeight / 2) + (c.getFont().getSize() / 2) - 1;

        g2d.drawString(title, x + insets.left + indent + 1, y + titleOffset + 1);

        g2d.setColor(fontColor);
        g2d.drawString(title, x + insets.left + indent, y + titleOffset);

        g2d.setColor(shadowColor);
        g2d.drawRect(x, y - 1, width - 1, height);
    }

    @Override
    public Insets getBorderInsets(Component c) {
        return insets;
    }

    @Override
    public boolean isBorderOpaque() {
        return false;
    }

}

CustomBorderTest.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * CustomBorderTest.java
 *
 * Created on 2009. 12. 23, 오전 10:44:25
 */

package swing_sample.customborder;

import java.awt.Color;
import javax.swing.UIManager;

/**
 *
 * @author Administrator
 */
public class CustomBorderTest extends javax.swing.JFrame {

    /** Creates new form CustomBorderTest */
    public CustomBorderTest() {

        changeSystemLookAndFeel();
      
        initComponents();

        customInit();
    }

    public void changeSystemLookAndFeel() {
        try {
            UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
        } catch (Exception e) {
            System.err.println("Couldn't use system look and feel.");
        }
    }
    public void customInit() {
        mainPanel.setBorder(new GradientTitleBorder("Title of main panel border", new Color(0x418EDC), new Color(0x6B91B8), Color.WHITE, 18));
        scrollPane.setBorder(new GradientTitleBorder("Title of tree scroll pane border"));
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        scrollPane = new javax.swing.JScrollPane();
        tree = new javax.swing.JTree();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        scrollPane.setViewportView(tree);

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 346, Short.MAX_VALUE)
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new CustomBorderTest().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JPanel mainPanel;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JTree tree;
    // End of variables declaration

}


Posted by 짱가쟁이
참조


- 결과화면


sun 에 기고된 기사를 토대로 따라 하다가 좀더 쉽게.. 사용하기 편한 예제를 만들어 보자는 취지로 만들게 됨.


1. DefaultMutableTreeNode 를 사용해서 트리노드를 만들다.
2. 생성된 노드로 TreeTableModel 을 만든다.
3. 데이터부가 완성되면 JTreeTable 을 생성하고
4. 여기서.. 아무 생각없이 (Netbeans 만 사용하다보니.. 사악한 마법사 땜시 고생함.) add 시켰다가 낭패봄.

    setViewportView() 사용해서 화면에 TreeTable을 보여줌.
// 1번.
DefaultMutableTreeNode root = getTreeNode();

// 2번.
TreeTableModel model = new BookTreeTableModel(root);

// 3번.
JTreeTable treeTable = new JTreeTable(model);

// 4번.
treeTableScrollPane.setViewportView(treeTable);
 
// TreeTable top-level container 배경색 변경.
treeTable.getParent().setBackground(Color.white);

 나머지 잡다한 코드들..
// 1번.

private DefaultMutableTreeNode getTreeNode() {
    DefaultMutableTreeNode root = makeRootNode("BOOK");
    DefaultMutableTreeNode java = makeRootNode("JAVA");
    DefaultMutableTreeNode novel = makeRootNode("NOVEL");

    root.add(java);
    root.add(novel);

    java.add(makeChildNode("concurrency in practice", "35,000원", "2009/12/16", "자바 병렬 프로그래밍"));      
    java.add(makeChildNode("Java FX", "29,000원", "2009/12/16", "자바 GUI 프로그래밍"));
    java.add(makeChildNode("Java Performance Fundamental", "29,000원", "2009/12/16", "JVM 관련 책"));

    novel.add(makeChildNode("람세스", "35,000원", "2009/12/16", "이집트 미친왕 이야기"));
    novel.add(makeChildNode("로마인 이야기", "29,000원", "2009/12/16", "로마사람들 전쟁이야기"));
    novel.add(makeChildNode("영웅문", "29,000원", "2009/12/16", "영웅이 문을 만드는 이야기"));
  
    return root;
}

private DefaultMutableTreeNode makeRootNode(String title) {
    Book book = new Book();
    book.setTitle(title);

    return new DefaultMutableTreeNode(book);
}

private DefaultMutableTreeNode makeChildNode(String title, String cost, String date, String description) {
    Book book = new Book();
    book.setTitle(title);
    book.setCost(cost);
    book.setDate(date);
    book.setDescription(description);
    return new DefaultMutableTreeNode(book);
}

BookTreeTableModel.java
package swing_sample.treetable.samplemodel;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import swing_sample.treetable.sunsource.AbstractTreeTableModel;
import swing_sample.treetable.sunsource.TreeTableModel;

/**
 *
 * @author Administrator
 */
public class BookTreeTableModel extends AbstractTreeTableModel {

    public BookTreeTableModel(Object root)
    {
        super(root);
    }

    /**
     * Error in AbstractTreeTableModel !!!
     * Without overriding this method you can't expand the tree!
     */
    public Class getColumnClass(int column) {
          switch (column)
          {
              case 0:
                    return TreeTableModel.class;
              default:
                    return Object.class;
          }
    }

    public Object getChild(Object parent, int index)
    {
          assert parent instanceof MutableTreeNode;
          MutableTreeNode treenode = (MutableTreeNode) parent;
          return treenode.getChildAt(index);
    }

    public int getChildCount(Object parent)
    {
          assert parent instanceof MutableTreeNode;
          MutableTreeNode treenode = (MutableTreeNode) parent;
          return treenode.getChildCount();
    }

    public int getColumnCount()
    {
        return 4;
    }

    public String getColumnName(int column)
    {
          switch (column)
          {
              case 0:
                    return "title";
              case 1:
                    return "cost";
              case 2:
                    return "date";
              case 3:
                    return "description";

              default:
                    return null;
          }

    }

    public Object getValueAt(Object node, int column)
    {
          assert node instanceof DefaultMutableTreeNode;
          DefaultMutableTreeNode treenode = (DefaultMutableTreeNode) node;
          Book book = (Book) treenode.getUserObject();
        
          switch (column)
          {
              case 0:
                  return book.getTitle();
              case 1:
                return book.getCost();
              case 2:
                  return book.getDate();
              case 3:
                return book.getDescription();
          default:
            return null;
          }

    }
}

Book.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package swing_sample.treetable.samplemodel;

/**
 *
 * @author Administrator
 */
public class Book {

    String title;
    String cost;
    String date;
    String description;

    public String getCost() {
        return cost;
    }

    public void setCost(String cost) {
        this.cost = cost;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String toString()
    {
        return title;
    }
}

Posted by 짱가쟁이
이전버튼 1 2 이전버튼