【问题标题】:Why does the JTable not show the Jtable heading even when added to JScrollPane?为什么即使添加到 JScrollPane,JTable 也不显示 Jtable 标题?
【发布时间】:2016-05-31 13:11:57
【问题描述】:
import javax.swing.*; 
import javax.swing.border.*;
import javax.swing.table.TableColumn;

import java.awt.*;

import static java.awt.GraphicsDevice.WindowTranslucency.*;

import java.awt.Checkbox;
import java.awt.Paint;
import java.awt.Toolkit;
import java.awt.event.*;

public class Main extends JPanel {

    static Object [][] Services = {{"Google.exe","Chickeaen.exe","Crp.exe"}};
    static String [] ColNames = {"Processes:","Crolly:","Haler:"};

    static JFrame Fram = new JFrame(); 
    static JTextField CBox = new JTextField();
    static JTable Tabs = new JTable(Services,ColNames);
    JScrollPane ScrollArea = new JScrollPane();
    static JButton ExitB = new JButton();
    Dimension ScreenSize = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
    Border BlackLineB = BorderFactory.createLineBorder(new Color(50,50,50));

    public Main() {

    Fram.setTitle("Jared Console");
    Fram.setUndecorated(true);
    Fram.setVisible(true); 
    Fram.setDefaultCloseOperation(Fram.EXIT_ON_CLOSE);
    Fram.setResizable(false);
    Fram.setSize((int)Math.round(ScreenSize.getWidth()*0.45),(int)Math.round(ScreenSize.getHeight()*0.33));
    Fram.setBackground(new Color(0,0,0,150));
    Fram.add(this);

    CBox.setSize((int)Math.round(Fram.getWidth()*0.80),(int)Math.round(Fram.getHeight()*0.25));
    CBox.setBackground(new Color(255,255,255));
    CBox.setBorder(BorderFactory.createCompoundBorder(BlackLineB,BorderFactory.createEmptyBorder(0,20,0,0)));
    CBox.setLocation((int)Math.round(Fram.getWidth()*0.1),(int)Math.round(Fram.getHeight()*0.70));
    CBox.setFont(new Font("Arial",Font.BOLD,20));
    CBox.setVisible(true);

    ScrollArea.setSize((int)Math.round(Fram.getWidth()*0.80),(int)Math.round(Fram.getHeight()*0.50)); 
    ScrollArea.setLocation((int)Math.round(Fram.getWidth()*0.10),(int)Math.round(Fram.getHeight()*0.10));
    ScrollArea.setBorder(BlackLineB);
    ScrollArea.setLayout(null);
    ScrollArea.setVisible(true);

    Tabs.setSize((int)Math.round(Fram.getWidth()*0.995),(int)Math.round(Fram.getHeight()*0.995));
    Tabs.setLocation((int)Math.round(Fram.getWidth()*0.003),(int)Math.round(Fram.getHeight()*0.005));
    Tabs.setFillsViewportHeight(true);
    Tabs.setBackground(new Color(255,255,255));

    this.add(CBox);
    this.add(Tabs);
    this.add(ExitB);
    ScrollArea.add(Tabs);
    this.add(ScrollArea);
    this.setBorder(BorderFactory.createLineBorder(new Color(50,50,50),5));
    this.setLayout(null);
    this.setBackground(new Color(0,0,0));
    this.setVisible(true);

    }

    public void paintComponent(Graphics Gla) { 
    Paint Plat = new GradientPaint(0f, 0f, new Color(0, 40, 0, 0), 0.0f, Fram.getHeight(), new Color(0, 0, 0, 150), true); //Made 200 equal to Fram Background Alpha.
    Graphics2D Quo = (Graphics2D)Gla;
    Quo.setPaint(Plat);
    Quo.fillRect(0, 0, Fram.getWidth(), Fram.getHeight());
    }

    public static void main(String[] args) {
    Main CScreen = new Main(); 
    GraphicsEnvironment GE = GraphicsEnvironment.getLocalGraphicsEnvironment(); // Have to study lines 57,58 and 59
    GraphicsDevice GD = GE.getDefaultScreenDevice();
    boolean CheckTransL = GD.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);

    if (!CheckTransL) {
        System.out.println("PERPIXEL TRANSLUCENT NOT SUPPORTED - LOL UPDATESCRUB!");
        System.exit(0);
    };  
    }

}

为什么即使添加到 JScrollPane,JTable 也不显示 Jtable 标题? 控制台也首先显示一条错误消息,然后很快消失并启动程序?所以是的,我想知道这有什么问题,你也可以告诉我这个程序中的一些坏习惯,比如它的输入方式。

【问题讨论】:

  • 因为你不会,把表包在JScrollPane
  • ScrollArea.setLayout(null); 我的,我的.. 如果这不是问题的一部分,我会吃掉我的帽子。 Java GUI 必须在不同的操作系统、屏幕尺寸、屏幕分辨率等上工作,在不同的语言环境中使用不同的 PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或 combinations of them 以及 white space 的布局填充和边框。
  • 顺便说一句 - 请学习常见的 Java 命名法(命名约定 - 例如EachWordUpperCaseClassfirstWordLowerCaseMethod()firstWordLowerCaseAttribute,除非它是 UPPER_CASE_CONSTANT)并始终如一地使用它。
  • public void paintComponent(Graphics Gla) { Paint Plat.. 应该是public void paintComponent(Graphics Gla) { super.paintComponent(Gla); Paint Plat.. 以避免绘制工件并确保绘制边框等。
  • "PERPIXEL TRANSLUCENT NOT SUPPORTED - LOL UPDATESCRUB!" - Perpixel alphing 支持也是操作系统问题,用户可能有硬件,但操作系统可能不支持 ;)

标签: java swing jtable transparency paintcomponent


【解决方案1】:

问题

  • null 布局。避免使用null 布局,像素完美的布局是现代 ui 设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正。详情请见Laying Out Components Within a Container
  • 过度使用staticstatic 不是你的朋友,你应该避免使用它。它不是跨对象通信机制,像这样过度使用会烧死你
  • 您实际上并没有将JTable 包装在JScrollPane
  • 通过不调用super.paintComponent来打破paint链,这将产生一系列精彩的绘画工件。请参阅 Painting in AWT and SwingPerforming Custom Painting 了解有关在 Swing 中如何进行绘画的更多详细信息
  • 您可能想通读一下Code Conventions for the Java TM Programming Language,这将使人们更容易阅读您的代码并让您更轻松地阅读其他人
  • 对 UI 的所有交互、创建和修改都应在事件调度事件的上下文中完成,以降低潜在的竞争条件、死锁和渲染工件的风险。详情请见Initial Threads
  • Toolkit.getDefaultToolkit().getScreenSize() 是屏幕可视空间的不良指标,它没有考虑操作系统特定的元素,例如停靠栏或任务栏,它们可能会让您的应用程序出现在它们下面(我真的,真的,真的很讨厌它当这种情况发生时)。使用适当的布局管理器和pack 围绕内容打包窗口。然后,您可以使用JFrame#setLocationRelativeTo 并将其传递给null,它将使框架在屏幕中居中

JScrollPane 问题...

简单的解决方案是使用JScrollPane 的构造函数将JTable 的引用传递给它...

static JTable Tabs = new JTable(Services,ColNames);
JScrollPane ScrollArea = new JScrollPane(Tabs);

但是,您稍后在代码中执行此操作...

this.add(Tabs);

这将从滚动窗格中删除表格以将其添加到您的面板中,因为组件只能有一个父级。

另一种选择是指定滚动窗格的视口的视图组件...

this.add(CBox);
//this.add(Tabs);
this.add(ExitB);
//ScrollArea.add(Tabs);
ScrollArea.setViewportView(Tabs);
this.add(ScrollArea);

您永远不应该将组件直接添加到滚动窗格(或它的底层视口),它们有自己的内部布局管理功能。相反,您需要将组件作为“视图”提供给JViewport

查看How to Use Scroll Panes了解更多详情。

【讨论】:

  • @mKorbel 我想过了一会儿,我就不再看了:P
【解决方案2】:

首先您应该在JScrollPaneViewPort 中添加一个JTable,以便JTableHeader 可见。

之后,您应该将您的 JTable 添加到 JScrollPane 和底层容器中。你应该:

  1. JTable 添加到JScrollPaneViewPort
  2. JScrollPane 添加到底层容器。

并删除将JTable 显式添加到容器的行。

祝你好运。

【讨论】:

    猜你喜欢
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多