Folgendes Problem:
Ich habe eine JTable in einer JScrollPane. Mit der Anweisung
kann man die JScrollPane anweisen, nach ganz unten zu scrollen. Das funktioniert auch in den meisten Fällen.
In folgendem Fall scrollt die JScrollPane aber nur ein wenig, aber nicht bis ganz unten.
Es muss irgendetwas mit dem CellRenderer zu tun haben, der die Aufgabe hat, in einer Zelle sowohl ein Bild als auch einen Text anzuzeigen. Denn wenn nur Text angezeigt wird, dann scrollt die JScrollPane problemlos bis nach ganz unten.
Das Ganze sieht dann so aus:
Kann mir jemand sagen, wieso die JScrollPane nicht bis ganz unten scrollt?
Hab die Klasse mal hier hochgeladen:
http://timeline1.ti.funpic.de/src.zip
Hier auch nochmal der Quellcode:
Test Klasse:
Modifizierte JTable:
Ich habe eine JTable in einer JScrollPane. Mit der Anweisung
Code:
scrollpane.getVerticalScrollBar().setValue(scrollpane.getVerticalScrollBar().getMaximum());
In folgendem Fall scrollt die JScrollPane aber nur ein wenig, aber nicht bis ganz unten.
Es muss irgendetwas mit dem CellRenderer zu tun haben, der die Aufgabe hat, in einer Zelle sowohl ein Bild als auch einen Text anzuzeigen. Denn wenn nur Text angezeigt wird, dann scrollt die JScrollPane problemlos bis nach ganz unten.
Das Ganze sieht dann so aus:
Kann mir jemand sagen, wieso die JScrollPane nicht bis ganz unten scrollt?
Hab die Klasse mal hier hochgeladen:
http://timeline1.ti.funpic.de/src.zip
Hier auch nochmal der Quellcode:
Test Klasse:
Code:
public class TimeLineTest extends JFrame{
TimeLine timeline;
public TimeLineTest(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
timeline = new TimeLine(5,10,true);
JScrollPane scrollpane = new JScrollPane(timeline);
this.add(scrollpane,BorderLayout.CENTER);
addData();
this.pack();
this.setSize(600,400);
this.setVisible(true);
// scroll down
scrollpane.getVerticalScrollBar().setValue(scrollpane.getVerticalScrollBar().getMaximum());
}
public static void main(String[] args) {
SwingUtilities.invokeLater (new Runnable(){
public void run () {
new TimeLineTest();
}
});
}
private void addData(){
for(int i=0;i<5;i++){
ArrayList<Object[]> columndata = new ArrayList<Object[]>();
int random = (int)(Math.random() * 40) + 2;
for(int j=0;j<random;j++){
columndata.add(new Object[]{"Bildtext",new ImageIcon(this.getClass().getResource("image1.png"))});
}
timeline.addColumn("Spalte", columndata);
}
}
}
Modifizierte JTable:
Code:
public class TimeLine extends JTable{
private ImageTableModel itm; // table model
private int maxRowHeight = 55; // maximum row height
/**
* Generates a new TimeLine object
* @param rows - number of rows of the default grid
* @param columns - number of columns of the default grid
* @param autoSizeRowHeight - auto adjust row height to the max row height
* @param autoSizeColumnWidth - auto adjust column width
*/
public TimeLine(int rows, int columns, boolean autoSizeRowHeight){
this.setTableHeader(null);
this.setDefaultRenderer(Object.class, new MyCellRenderer(this));
itm = new ImageTableModel();
itm.initGrid(rows, columns);
setModel(itm); // set the table model
}
/**
* Adds a new column to the table
* @param columnName - The column name
* @param columndata - The row values for this column.
* Object[0] contains the cell text, object[1] contains the ImageIcon
*/
public void addColumn(String columnName, ArrayList<Object[]> columndata){
itm.addColumn(columnName, columndata);
}
/**
* Cell renderer for this table
*/
class MyCellRenderer extends DefaultTableCellRenderer{
private TimeLine theTimeLine;
public MyCellRenderer(TimeLine timeline){
this.theTimeLine = timeline;
setHorizontalAlignment( CENTER );
setVerticalTextPosition(JLabel.BOTTOM);
setHorizontalTextPosition(JLabel.CENTER);
}
public void setValue(Object value) {
Object[] a = (Object[])value;
if(value == null){ // empty cell
setIcon(null);
super.setValue(value);
}
else if (a[1] instanceof Icon) { // normal cell with text and image
setIcon((Icon) a[1]);
setText((String)a[0]);
this.setAlignmentY(JLabel.BOTTOM_ALIGNMENT);
theTimeLine.setRowHeight(maxRowHeight);
}
else if(a[1] == null && a[0] instanceof String){
setText((String)a[0]);
setIcon(null);
}
else {
setIcon(null);
super.setValue(value);
}
}
}
/**
* The table model for this timeline *
*/
class ImageTableModel extends AbstractTableModel{
private ArrayList<String> columnnames; // holds the column names
private ArrayList<ArrayList<Object[]>> data; // holds the table data
private int maxRowCount;
private int columnCursor; // points on the current column
public ImageTableModel(){
columnnames = new ArrayList<String>();
data = new ArrayList<ArrayList<Object[]>>();
maxRowCount = 0;
columnCursor = 0;
}
public Object getValueAt(int row, int column){
if (data.get(column).size()-1<row){
return null;
}
else{
return data.get(column).get(row);
}
}
public int getRowCount(){
return maxRowCount;
}
public int getColumnCount(){
return columnnames.size();
}
public String getColumnName( int columnIndex ){
return columnnames.get(columnIndex);
}
/**
* Adds a new column to the table
* @param columnName - The column name
* @param columndata - The row values for this column.
*/
public void addColumn(String columnName, ArrayList<Object[]> columndata){
if(columnCursor >= columnnames.size()){
columnnames.add(columnName);
data.add(rotateFillList(columnName,columndata));
}
else{
columnnames.set(columnCursor, columnName);
data.set(columnCursor, rotateFillList(columnName,columndata));
}
SwingUtilities.invokeLater (new Runnable(){ // fixes a nasty java vector bug
public void run () {
fireTableStructureChanged();
fireTableDataChanged();
}
});
columnCursor++;
}
public void initGrid(int rows, int columns){
for(int i=0;i<columns;i++){
ArrayList<Object[]> newdata = new ArrayList<Object[]>();
for(int j=0;j<rows;j++){
newdata.add(null);
}
columnnames.add(String.valueOf(i));
data.add(newdata);
maxRowCount = rows;
}
SwingUtilities.invokeLater (new Runnable(){ // fixes a nasty java vector bug
public void run () {
fireTableStructureChanged();
fireTableDataChanged();
}
});
}
/**
* Rotates the list. If list.size() is smaller than
* maxRowCount the list if filled with null values
* This generates the bottom up effect
* @param columnName - The column name
* @param list
* @return list
*/
private ArrayList<Object[]> rotateFillList(String columnName, ArrayList<Object[]> list){
list.add(0,new Object[]{columnName,null}); // set column name to be on the bottom
if(maxRowCount < list.size()){
// adjust all rows to the new maxRowCount
maxRowCount = list.size();
for(int i=0;i<data.size();i++){
int diff = maxRowCount - data.get(i).size();
for(int j=0;j<diff;j++){
data.get(i).add(0,null);
}
}
}
else { // fill with null values
int diff = maxRowCount - list.size();
for(int i=0;i<diff;i++){
list.add(null);
}
}
ArrayList<Object[]> rotatedList = new ArrayList<Object[]>();
for(int i= list.size()-1;i>=0;i--){ // rotate list
rotatedList.add(list.get(i));
}
return rotatedList;
}
}
}