쉽게 번 돈은 쉽게 날려버린다고.. 이거 어딘가에서 쉽게 찾아 사용하던 코드라 그런지.. 또 사용할려고 하니.. 도통 기억이 안남..

보통 테이블에서 셀을 수정하다가(셀이 editing 상태임) 버튼을 눌러서 수정된 값을 저장할려고 시도하는 경우가 있다. 그런데 JTable 이라는 넘은 셀이 수정중이면 엔터를 치거나, 아니면 포커스를 변경해줘야지 값이 변경된다. 물론 사용자한테 책임을 떠 넘기고 '니들이 사용할 때 잘 사용해라' 라고 할 수 있겠지만, 보통은 이런식으로 작업을 하는 사람이 없을 듯 싶다.

위 문제를 해결하는 방법을 또 찾기 싫어서 여기에 올림 .. 쩌ㅃ~

1. editCellAt() 를 이용해서 현재 수정중인 값을 가져온다.

2. setValueAt() 넘을 사용해서 가져온 값으로 변경하면 땡.


editCellAt()   : 현재 수정중인 셀의 값을 가져오는 넘.

setValueAt() : 특정 셀에 값을 삽입한다.

editingStopped()  : 처음에 이넘을 사용하면 될듯 싶었지만. 저넘은 단순히 에디팅이 끝났다고 알려주기만 하는듯 싶다. 뭐.. 엄밀히 말해서 셀의 에디팅 상태를 종료하는 넘으로 해석하면 될듯.

 

table.setValueAt(table.editCellAt(table.getSelectedRow(), table.getSelectedColumn()), table.getSelectedRow(), table.getSelectedColumn());

table.editingStopped(null);

Posted by 짱가쟁이

하나만 만들어 놓고 언제나 사용할 수 있는 Table Model 을 만들자는 취지로 시작했지만.. Table 의 요구사항 변경에 따라 수정 할 수 밖에 없다. 좀 아쉬운 감이 있지만 모든걸 다 적용시키기는 힘들다는 결론에 다다르고 단순히 범용적으로 사용할 수 있는 넘 하나만 만들었다.

TableModel 은 column name 과 data 두개의 부분으로 나눠지는데.. 이 두개만 생성해 model에 등록하면 알아서 동작하는 넘으로 작성되었다. Reflection 기능을 이용하니 손쉽게 작성된듯...


MyTableModel.java

AbstractTableModel 클래스를 상속받아 구현된 단순한 넘. 기본 골격은 (http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#validtext) 참조했으며 신규 추가된 부분이 data 와 header 부분을 Value Object로 변경한 부분이다. 물론 변경된 사항에 따라서 column name 과 data get, set 부분이 수정되었다.

import javax.swing.table.AbstractTableModel;

 /**
 *
 * @author Administrator
 */
public class MyTableModel extends AbstractTableModel {

    private AbstractTableVo[] data;
    private CustomTableColumnName[] columnNames;

    public Object[] longValues;

    public Object[] getLongValues() {
        return longValues;
    }

    public void setLongValues(Object[] longValues) {
        this.longValues = longValues;
    }

    public CustomTableColumnName[] getColumnNames() {
        return columnNames;
    }

    public void setColumnNames(CustomTableColumnName[] columnNames) {
        this.columnNames = columnNames;
    }

   
    public AbstractTableVo[] getData() {
        return data;
    }

    public void setData(AbstractTableVo[] data) {
        this.data = data;
    }

    public String getColumnName(int col) {
        return columnNames[col].getName();
    }


    public int getRowCount() {
        return data.length;
    }

    public int getColumnCount() {
        return columnNames.length;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return data[rowIndex].getValueAt(columnNames[columnIndex].getId());
    }
   
    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    public boolean isCellEditable(int row, int col) {
        return true;
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    public void setValueAt(Object value, int row, int col) {

        data[row].setValueAt(value, columnNames[col].getId());

    }

    /*
     * JTable uses this method to determine the default renderer/
     * editor for each cell.  If we didn't implement this method,
     * then the last column would contain text ("true"/"false"),
     * rather than a check box.
     */
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

}


SampleVo.java
- 샘플로 작성된 Table Data Value 객체. AbstractTableVo 클래스를 상속받아야 하는 rule 만 지켜주면 만사형통임.

/**
 *
 * @author Administrator
 */
public class SampleVo extends AbstractTableVo {

    private String firstName;
    private String lastName;
    private String sport;
    private Integer ofYears;
    private Boolean vegetarian;
       
    public Boolean getVegetarian() {
        return vegetarian;
    }

    public void setVegetarian(Boolean vegetarian) {
        this.vegetarian = vegetarian;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getOfYears() {
        return ofYears;
    }

    public void setOfYears(Integer ofYears) {
        this.ofYears = ofYears;
    }

    public String getSport() {
        return sport;
    }

    public void setSport(String sport) {
        this.sport = sport;
    }  
}


AbstractTableVo.java
- CustomTableColumnName, SampleVo 클래스 들이 규칙에 따라 작성되면 TableModel 과 연결되어 알아서 작동한다.

import java.lang.reflect.Method;

/**
 *
 * @author Administrator
 */
public abstract class AbstractTableVo {

    public void setValueAt(Object value, String id) {
         try {

            String methodName = "set" + id.substring(0, 1).toUpperCase() + id.substring(1, id.length());

            Method method = this.getClass().getMethod(methodName , new Class[]{value.getClass()});

            method.invoke(this, value);
        } catch(Exception e) {

        }
    }
  
    public Object getValueAt(String id) {

        try {

            String methodName = "get" + id.substring(0, 1).toUpperCase() + id.substring(1, id.length());

            System.out.println("Method Name : " + methodName);

            Method method = this.getClass().getMethod(methodName ,null);

            return method.invoke(this, null);
        } catch(Exception e) {

        }
        return null;
    }
}


CustomTableColumnName.java
- table의 header 명을 가지는 클래스로 name 필드는 컬럼명을 의미하며, id 는 컴럼명을 의미하는 키로 SampleVo 의 필드명과 일치해야 한다.    

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

    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


사용법
Model 을 만드는 부분이 화면에 보여질 데이터를 작성하는 것이기 때문에 어쩔 수 없이 무식하고 지져분해질 수 밖에 없는듯하다. 좀더 좋은 방법이 있겠지만, 귀찮니즘 때문인지 단순히 데이터를 무식하게 쌓기만 했다. 사용은 각자가 알아서 하면 될듯하다.

SampleVo 를 토대로 작성했기 때문에 다른 Data Value Object 작성 시 아래 코드는 참조용으로만 사용해야 할듯.

private MyTableModel myTableModel = new MyTableModel();

// Table Model 초기화

private void initTable() {       

        SampleVo[] tableDataValues;
        CustomTableColumnName[] tableColumnNames;

        // table data 초기화

        tableDataValues = new SampleVo[5];
        setData(tableDataValues, 0, "Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(false));
        setData(tableDataValues, 1, "Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(true));
        setData(tableDataValues, 2, "Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(false));
        setData(tableDataValues, 3, "Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(true));
        setData(tableDataValues, 4, "Mary", "Campione", "Snowboarding", new Integer(5), new Boolean(true));
        myTableModel.setData(tableDataValues);

        // column name 초기화
        tableColumnNames = new CustomTableColumnName[5];
        setColumnName(tableColumnNames,0, "firstName", "First Name");
        setColumnName(tableColumnNames,1, "lastName", "Last Name");
        setColumnName(tableColumnNames,2, "sport", "Sport");
        setColumnName(tableColumnNames,3, "ofYears", "# of Years");
        setColumnName(tableColumnNames,4, "vegetarian", "Vegetarian");
        myTableModel.setColumnNames(tableColumnNames);

       // column 최대 사이즈를 구하기 위해서..
       Object[] longValues = {"Sharon", "Campione", "None of the above", new Integer(20), Boolean.TRUE};
       myTableModel.setLongValues(longValues);
    }

     public void setColumnName(CustomTableColumnName[] tableColumnNames, int offset, String id, String name) {
        tableColumnNames[offset] = new CustomTableColumnName();
        tableColumnNames[offset].setId(id);
        tableColumnNames[offset].setName(name);
    }
   
    public void setData(SampleVo[] tableDataValues, int offset, String firstName, String lastName, String sport, Integer integer, Boolean boo) {
        tableDataValues[offset] = new SampleVo();
        tableDataValues[offset].setFirstName(firstName);
        tableDataValues[offset].setLastName(lastName);
        tableDataValues[offset].setSport(sport);
        tableDataValues[offset].setOfYears(integer);
        tableDataValues[offset].setVegetarian(boo);
    }



Posted by 짱가쟁이
2010. 6. 30. 00:36

// Emits an audio beep

Toolkit.getDefaultToolkit().beep();

Posted by 짱가쟁이

<실행화면>


Netbeans IDE 에서 Tree Cell 을 변경하는 방법.

1. DefaultTreeCellRenderer 를 상속받아 CustomTreeCellRenderer.java 작성

- Cell 의 배경색과 Selected 된 Cell 의 배경색을 변경한다.

2. Netbeans 에서 변경하고 싶은 Tree의 Properties 에서 cellRenderer 'Custom code' 선택 후 [new CustomTreeCellRenderer()] 변경.

위 1, 2 번을 수행하면 실행화면과 같이 Cell 의 background color 이 변경된다.


Example

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

package swing_sample.tree.cellrenderer;

import java.awt.Color;
import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;

/**
 *
 * @author Administrator
 */
public class CustomTreeCellRenderer extends DefaultTreeCellRenderer {

    @Override
    public Component getTreeCellRendererComponent (
            JTree tree,
            Object value,
            boolean selected,
            boolean expanded,
            boolean leaf,
            int row,
            boolean hasFocus)
    {
        JComponent comp = (JComponent) super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
        comp.setOpaque(true);

        if(selected) {
            comp.setBackground(Color.DARK_GRAY);
        } else {
            comp.setBackground(tree.getBackground());
        }
        return comp;
    }
}

Posted by 짱가쟁이
출처

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 짱가쟁이
참조

1. Services Client-side Code 생성
- build.xml
  : Ant Build 하기 전에 Web Service Server 를 실행시켜야 함.
<project default="wsimport">

  <target name="wsimport">
    
    <exec executable="wsimport">    
      <arg line="-keep -s ./src -p com.hoon.webclient.service
          -d ./bin http://localhost:8080/hello?wsdl"/>
    </exec>
  
   <exec executable="wsimport">    
      <arg line="-keep -s ./src -p com.hoon.webclient.service
          -d ./bin http://localhost:8080/login?wsdl"/>
    </exec>
  
  </target>

</project>

- Ant Build 실행하면 코드 생성됨 (com.hoon.webclient.service)


2. Client Application 생성

LoginClient.java
package com.hoon.webclient.login;

import javax.xml.ws.BindingProvider;

import com.hoon.webclient.service.SampleLogin;
import com.hoon.webclient.service.SampleLoginService;

public class LoginClient {

public static void main(String args[]) {
 
        SampleLoginService shs = new SampleLoginService();
 
        SampleLogin sh = (SampleLogin) shs.getSampleLoginPort();
 
        ((BindingProvider)sh).getRequestContext().put(BindingProvider.
            ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/login");

        System.out.println( ((BindingProvider)sh).toString() );

        System.out.println(sh.checkLogin("bbaeggar", "000"));
굵게
    }
}

SayHelloClient.java
package com.hoon.webclient.hello;

import javax.xml.ws.BindingProvider;

import com.hoon.webclient.service.SayHello;
import com.hoon.webclient.service.SayHelloService;

public class SayHelloClient {

 public static void main(String args[]) {
 
        SayHelloService shs = new SayHelloService();
 
        SayHello sh = (SayHello) shs.getSayHelloPort();
 
        ((BindingProvider)sh).getRequestContext().put(BindingProvider.
            ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/hello");

        System.out.println( ((BindingProvider)sh).toString() );

        System.out.println(sh.getGreeting("bbaeggar"));
    }
}


3. Run

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 짱가쟁이
JTable 이라는 놈은 최상위 컨테이너 위에 그려지기 때문에 top-level container 의 배경색을 변경하면 밑의 그림처럼 수정됨.

java.lang.Object
  - java.awt.Component
      - java.awt.Container
          - javax.swing.JComponent
              - javax.swing.JTable

<변경전>

<변경후>

- code
table.getParent().setBackground(Color.white);

ps.
단순히 table 의 배경색으로 변경하고 싶은 경우.. (1.6 이상부터 지원)
table.setFillsViewportHeight(true);

Posted by 짱가쟁이