TableColumnModelListener()
을 사용하여 열의 크기가 변경된 것을 감지하고 columnMarginChanged()
메서드에서 실행하려는 일부 코드가있는 JTable이 있습니다.자바 JTable 감지 사용자가 열 크기 조정
사용자가 다른 열의 결과로 열의 크기를 조정했는지 어떻게 결정합니까?
나는 ChangeEvent.getSource()
으로 시작해야한다고 생각하지만 거기서 어디로 가야할지 모르겠습니다.
감사합니다.
TableColumnModelListener()
을 사용하여 열의 크기가 변경된 것을 감지하고 columnMarginChanged()
메서드에서 실행하려는 일부 코드가있는 JTable이 있습니다.자바 JTable 감지 사용자가 열 크기 조정
사용자가 다른 열의 결과로 열의 크기를 조정했는지 어떻게 결정합니까?
나는 ChangeEvent.getSource()
으로 시작해야한다고 생각하지만 거기서 어디로 가야할지 모르겠습니다.
감사합니다.
하나의 가능한 접근 방식을 제공 할 수 있습니다. 같은 문제를 해결하려고했는데, 열 너비에 대한 정보를 디스크에 직렬화하여 다음에 응용 프로그램에서 테이블을 열면 열 너비를 적절히 복원 할 수있었습니다. 여기 간다 :
1 단계 - 당신의 JTable을 무시하고
class MyTable extends JTable {
private boolean isColumnWidthChanged;
public boolean getColumnWidthChanged() {
return isColumnWidthChanged;
}
public void setColumnWidthChanged(boolean widthChanged) {
isColumnWidthChanged = widthChanged;
}
}
2 단계 그것에 부울 속성을 추가 - (A TableColumnModelListener 추가) 테이블
private class TableColumnWidthListener implements TableColumnModelListener
{
@Override
public void columnMarginChanged(ChangeEvent e)
{
/* columnMarginChanged is called continuously as the column width is changed
by dragging. Therefore, execute code below ONLY if we are not already
aware of the column width having changed */
if(!tableObj.hasColumnWidthChanged())
{
/* the condition below will NOT be true if
the column width is being changed by code. */
if(tableObj.getTableHeader.getResizingColumn() != null)
{
// User must have dragged column and changed width
tableObj.setColumnWidthChanged(true);
}
}
}
@Override
public void columnMoved(TableColumnModelEvent e) { }
@Override
public void columnAdded(TableColumnModelEvent e) { }
@Override
public void columnRemoved(TableColumnModelEvent e) { }
@Override
public void columnSelectionChanged(ListSelectionEvent e) { }
}
에 3 단계 - 테이블 수신기에 마우스 수신기 추가
private class TableHeaderMouseListener extends MouseAdapter
{
@Override
public void mouseReleased(MouseEvent e)
{
/* On mouse release, check if column width has changed */
if(tableObj.getColumnWidthChanged())
{
// Do whatever you need to do here
// Reset the flag on the table.
tableObj.setColumnWidthChanged(false);
}
}
}
참고 : 내 응용 프로그램에서 TableHeaderMouseListener 및 TableColumnWidthListener 클래스는 내 기본 응용 프로그램 클래스의 개인 내부 클래스입니다. 내 주요 응용 프로그램 클래스는 관찰되는 테이블의 참조를 유지합니다. 따라서 이러한 내부 클래스는 테이블 인스턴스에 액세스 할 수있었습니다. 분명히, 설정에 따라 테이블 인스턴스를 다른 클래스에서 사용할 수 있도록 적절한 작업을 수행해야합니다. 희망이 도움이!
(아직 요구 사항을 얻지 못했습니다 - 너비를 항상 간단하게 저장하는 것이 좋겠습니까?) - 마커 : 커서를 사용하는 대신 매우주의해야합니다 :-) 헤더를 사용하십시오 resizingColumn : 그것입니다!= 사용자가 크기를 조정하는 중에 만 null입니다. 그것은 JXTableHeader가 패킹을 지원하고 크기를 조정할 때조차도 정렬을 트리거하는 성가신 핵심 버그를 수정하는 방법입니다. – kleopatra
한 가지 방법은 애플리케이션이 종료 될 때 모든 열 너비를 간단히 직렬화하는 것입니다 (어쩌면 windowClosing 메소드를 통해). WindowListener)를 호출합니다. 이것이이 질문을 게시 한 사람에게 올바른 접근법 일 수 있습니다. 열 너비를 점진적으로 serialize해야하는 이유는 행/열이 작성/삭제 될 때마다 내 JTable이 파괴되고 처음부터 재생성되기 때문입니다. (이것은 이상하게 들릴지 모르겠지만 공개 포럼에서 공개 할 수없는 이유가 있습니다.) 따라서 원래의 너비를 되 찾는 방법은 점진적으로 순차적으로 나열하는 것입니다. – eternaln00b
아마도 좀 더 자세히 설명해 드릴 수 있습니다. :) 아시다시피, 내 JTable은보다 정교한 백엔드의 입력 양식입니다. 사용자가 애플리케이션의 JTable을 변경하면 특정 작업이 백그라운드에서 사용자를 위해 자동 생성됩니다. 그래서 제 JTable은 본질적으로 마법사입니다. 테이블이 백그라운드에서 자동 생성 된 것을 정확히 반영하도록하려면 자동 생성 된 오브젝트를 구문 분석하고 테이블을 다시 작성해야합니다. 이 작업을 수행하지 않으면 프로그래밍 오류로 인해 테이블과 자동 생성 개체가 분기되기 시작하고 더 이상 진실이 없음을 알 수 있습니다. – eternaln00b
일반적으로 완료된 열 끌기 또는 완료된 열 크기 조정을 알리 길 원합니다. 예 :
interface SGridModel {
public void columnMoved(int oldLocation, int newLocation);
public void columnResized(int column, int newWidth);
}
이 아니지만, 꽤 당신이 원하는 것을 할 것입니다 다음과 같이
class SColumnListener extends MouseAdapter implements TableColumnModelListener {
private final Logger log = Logger.getLogger(getClass());
private final SGridModel model;
private int oldIndex = -1;
private int newIndex = -1;
private boolean dragging = false;
private boolean resizing = false;
private int resizingColumn = -1;
private int oldWidth = -1;
SColumnListener(SGridModel model){
this.model = model;
}
@Override
public void mousePressed(MouseEvent e) {
// capture start of resize
if(e.getSource() instanceof JTableHeader) {
TableColumn tc = ((JTableHeader)e.getSource()).getResizingColumn();
if(tc != null) {
resizing = true;
resizingColumn = tc.getModelIndex();
oldWidth = tc.getPreferredWidth();
} else {
resizingColumn = -1;
oldWidth = -1;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// column moved
if(dragging && oldIndex != newIndex) {
model.columnMoved(oldIndex, newIndex);
log.info("column moved: " +oldIndex+" -> "+newIndex);
}
dragging = false;
oldIndex = -1;
newIndex = -1;
// column resized
if(resizing) {
if(e.getSource() instanceof JTableHeader) {
TableColumn tc = ((JTableHeader)e.getSource()).getColumnModel().getColumn(resizingColumn);
if(tc != null) {
int newWidth = tc.getPreferredWidth();
if(newWidth != oldWidth) {
model.columnResized(resizingColumn, newWidth);
log.info("column resized: " +resizingColumn+" -> "+newWidth);
}
}
}
}
resizing = false;
resizingColumn = -1;
oldWidth = -1;
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
// capture dragging
dragging = true;
if(oldIndex == -1){
oldIndex = e.getFromIndex();
}
newIndex = e.getToIndex();
}
@Override
public void columnMarginChanged(ChangeEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
}
테이블에 추가 :
table.getColumnModel().addColumnModelListener(cl);
table.getTableHeader().addMouseListener(cl);
간단한 해결책은 듣고 수 있습니다 (이 사용자 상호 작용에서 한 번만 발생하는) 마우스 릴리즈 이벤트에서 그 동안 열 크기가 변경되었는지 확인하십시오. 아래의 코드를 사용하여 열 순서 변경 및 크기 변경을 수신 대기합니다.
getTableHeader().addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent arg0)
{
String colNamesAndSizes = "";
for(int i=0;i<getColumnModel().getColumnCount();i++) {
if(i>0) colNamesAndSizes += ",";
TableColumn column = getColumnModel().getColumn(i);
colNamesAndSizes += column.getHeaderValue();
colNamesAndSizes += ":";
colNamesAndSizes += column.getWidth();
}
// check if changed, if yes, persist...
}});
변경하지 않는 한, 소스는 항상 'fireColumnMarginChanged()'를 통해 테이블의 'DefaultTableColumnModel'이됩니다. 어떤 문제를 해결하려고합니까? – trashgod
절대 안됩니다. @ trashgod의 질문을 반복하십시오 : 왜? – kleopatra
열 크기를 변경하는 코드의 경우 변경하기 전에 항상 수신기를 비활성화 또는 제거하고 변경 한 다음 반응을 나타내거나 수신기를 다시 추가 할 수 있습니다. – Robin