Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Многострочные заголовки в JTable


Автор: H4nter 1.10.2008, 02:35
Собственно сабж smile 
Просто в таблице довольно большие заголовки, а сократить не получается. Обычная "растяжка" колонок не особо как то смотрится... хотелось бы осуществить именно многострочные заголовки.

Автор: 1024 2.10.2008, 12:49
JTable setTableHeader

Автор: jeank 3.10.2008, 15:12
Как какая то проблема, так сразу на форум и бам новый топик...
Гуглить надо сперва - это тысячи раз показывалось, достаточно написать в запросе  - "multi line headers JTable".

Автор: H4nter 4.10.2008, 15:32
1024, так не получится, будет однострочный

jeank, да лан, а я не знал. Открыл Америку блин. Молодец, подай на премию... за такую "гениальную" идею точно  дадут smile 

Уже нашел, стоило только расширить стандартный JList.

Автор: Старовъръ 4.10.2008, 15:35
Вобще-то, джинк прав, лучше бы его послушал, чем паясничал.

Автор: H4nter 4.10.2008, 15:40
Старовъръ, вообще то это не "паясничать". Просто следует думать, прежде чем так вот отвечать. Может человек не так искал, или еще что. Почему просто нельзя дать ответ, без этих снисходительного тона? Хотя это вопрос конечно же менталитета конкретного человека...

Автор: dorogoyIV 4.10.2008, 19:43
H4nter, есть очень простой способ - HTML в помощь 
Код

import javax.swing.*;

public class TableHeaderMultiLine extends JFrame
{
 public TableHeaderMultiLine()
 {
  Object [][] data = new Object [][] {{"1", "2"}, {"3", "4"}};
  Object [] name = new Object [] {("<html>1<br>2<br>3"),
          ("<html>one<br>two<br>three")};
  JTable table = new JTable(data, name);
  add(new JScrollPane(table));
 }

 public static void main(String [] args)
 {
  JFrame f = new TableHeaderMultiLine();
  f.setBounds(100, 100, 400, 300);
  f.setDefaultCloseOperation(3);
  f.setVisible(true);
 }
}


а если надо что то посложнее, то надо писать свой рендерер

ну вот еще как можно делать (правда здесь для ячеек, но можно сделать и для Header)
Код

package TransformText;

import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TransformText extends JFrame
{
 JTable table;
 String [] columnNames = {"one", "two", "three"};
 String [][] data = {{"111", "222", "333"},{"aaa", "bbb", "ccc"},
                     {"444", "55555555555", "666"}, {"777", "888", "999"}};

 public TransformText()
 {
  table = new JTable(data, columnNames);
  table.setRowHeight(getRowHeight());

   // здесь вводим угол поворота текста ячеек в градусах
  TableRenderer renderer = new TableRenderer(-30);
   // а можно задать угол конкретной ячейке
//  TableRenderer renderer = new TableRenderer(-30, 2, 1);

  for(int i = 0; i < columnNames.length; i++)
   table.getColumnModel().getColumn(i).setCellRenderer(renderer);

  add(new JScrollPane(table));

  table.getModel().addTableModelListener(new TableModelListener()
  {
   public void tableChanged(TableModelEvent e)
   {
    table.setRowHeight(getRowHeight());
   }
  });
 }

  // в этом методе подсчитывается предпочтительная высота строк
  // в таблице, при угле поворота текста ячейки 90 градусов.
  // мне лень было сделать расчет поточнее ;)
 public int getRowHeight()
 {
  FontMetrics fm = table.getFontMetrics(table.getFont());
  int string_width = 0;

  for(int i = 0; i < data.length; i++)
   for(int j = 0; j < data [i].length; j++)
   {
    int width = fm.stringWidth(data [i][j]);
    if(string_width < width)
     string_width = width;
   }
  return string_width + 8;
 }

 public static void main(String [] args)
 {
  JFrame f = new TransformText();
  f.setBounds(100, 100, 400, 300);
  f.setDefaultCloseOperation(3);
  f.setVisible(true);
 }
}

class TableRenderer extends JComponent
                    implements TableCellRenderer
{
 int angle, r = -1, c = -1;

 TableRenderer(int angle)
 {
  this(angle, -1, -1);
 }

 TableRenderer(int angle, int r, int c)
 {
  this.angle = angle;
  this.r = r;
  this.c = c;
 }

 public Component getTableCellRendererComponent(JTable table, Object value,
                     boolean isSelected, boolean hasFocus, int row, int column)
 {
  if(r < 0 && c < 0)
   return new MyLabel(value == null ? "" : value.toString(), angle);
  if(r == row && c == column)
   return new MyLabel(value == null ? "" : value.toString(), angle);
  else
   return new JLabel(value == null ? "" : value.toString(), JLabel.CENTER);
 }
}

class MyLabel extends JLabel
{
 String s;
 int angle;

 MyLabel(String s, int angle)
 {
  this.s = s;
  this.angle = angle;
 }

 public void paintComponent(Graphics g)
 {
  super.paintComponent(g);

  AffineTransform at = new AffineTransform();
  at.rotate(Math.toRadians(angle), getWidth()/2, getHeight()/2);
  ((Graphics2D)g).transform(at);

  FontMetrics fm = getFontMetrics(getFont());
  int string_width = fm.stringWidth(s);

  g.drawString(s, (getWidth() - string_width)/2, getHeight()/2);
 }
}

Автор: jeank 6.10.2008, 10:40
Цитата

jeank, да лан, а я не знал. Открыл Америку блин. Молодец, подай на премию... за такую "гениальную" идею точно  дадут smile 

Никого не хотел обидеть...
Просто думал что лингво или переводчик на машине есть у всех, в чем был "затык" не пойму. А все понял - слово "многострочный" наверное  smile 

Автор: H4nter 7.10.2008, 02:34
jeank, ну инглишь я хорошо читаю, а вот с русского на английский не всегда хорошо могу перевести, особенно в 4 утра  smile  Лан, все ок, никто ни на кого не обижается- все гудsmile 


dorogoyIV, а вот с HTML довольно интересно, а главное работает! (если только не ставить определенный стиль... если поставить, то вторая и 3я строки уходят вниз...) я пробовал просто знаки перевода \n\t но так не работало... а HTML он почему-то воспринимает... интересно...

Второй вариант вообще жесть... перересовывать в данной проблеме, это конечно сродни изобретению колеса...
Вот как я осуществил многострочный вариант заголовка 

Код


public class MultiLineHeaderRenderer extends JList implements TableCellRenderer {
  public MultiLineHeaderRenderer() {
    setOpaque(true);
    setForeground(UIManager.getColor("TableHeader.foreground"));
    setBackground(UIManager.getColor("TableHeader.background"));
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel)renderer).setHorizontalAlignment(JLabel.CENTER);
    setCellRenderer(renderer);
  }

  public Component getTableCellRendererComponent(JTable table, Object value,
                   boolean isSelected, boolean hasFocus, int row, int column) {
    setFont(table.getFont());
    String str = (value == null) ? "" : value.toString();
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector<String> v = new Vector<String>();
    try {
      while ((line = br.readLine()) != null) {
        v.addElement(line);
      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    setListData(v);
    return this;
  }
}

Автор: dorogoyIV 7.10.2008, 11:17
Цитата(H4nter @  7.10.2008,  02:34 Найти цитируемый пост)
Второй вариант вообще жесть... перересовывать в данной проблеме, это конечно сродни изобретению колеса...

если заголовок столбца длинный, некрасиво разбивать его на слоги или буквы - можно повернуть на 90 градусов

Автор: H4nter 7.10.2008, 19:04
Цитата(dorogoyIV @ 7.10.2008,  12:17)
Цитата(H4nter @  7.10.2008,  02:34 Найти цитируемый пост)
Второй вариант вообще жесть... перересовывать в данной проблеме, это конечно сродни изобретению колеса...

если заголовок столбца длинный, некрасиво разбивать его на слоги или буквы - можно повернуть на 90 градусов

согласен, в иных случаях это действительно полезнее...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)