I have a JTable that is wider than the JScrollPane it is contained in (essentially defined like this):
我有一个比它包含的JScrollPane更宽的JTable(基本上定义如下):
JTable table = new JTable(model);
// I change some things like disallowing reordering, resizing,
// disable column selection, etc.
// I set the default renderer to a DefaultTableCellRenderer
// getTableCellRendererComponent, and then changes the color
// of the cell text depending on the cell value
JPanel panel = new JPanel(new BorderLayout(0, 5));
panel.add(new JScrollPane(table), BorderLayout.CENTER);
// add other stuff to the panel
this.add(panel, BorderLayout.CENTER);
Before I changed the look and feel from the default to Nimbus, I was able to scroll left and right in the JTable. (I like the Mac LaF, but it isn't supported on Windows, and the Windows LaF is ugly in my opinion),
在我将默认的外观改为Nimbus之前,我能够在JTable中左右滚动。 (我喜欢Mac LaF,但它在Windows上不受支持,而且我认为Windows LaF很丑陋),
I took the following code straight from the Java Tutorials:
我直接从Java教程中获取了以下代码:
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look
// and feel.
}
I recompiled and ran the code without changing any of the table definition stuff above, and I couldn't scroll horizontally in the JTable anymore.
我重新编译并运行代码而不更改上面的任何表定义,我无法再在JTable中水平滚动。
I can't seem to find anything on what would cause this. Is this the normal behavior for Nimbus, or can I change it? If so, how? or should I just try a different look and feel?
我似乎无法找到导致这种情况的任何内容。这是Nimbus的正常行为,还是可以改变它?如果是这样,怎么样?或者我应该尝试不同的外观和感觉?
EDIT:
I discovered two things:
我发现了两件事:
-
I made a new class extending JTable to test this. I copied the code for
getScrollableUnitIncrement
from the JTable source, and added print statements. The orientation that is passed seems to always beSwingConstants.VERTICAL
, while in the default Look and Feel (Mac Aqua or whatever), both horizontal and vertical scrolling works. I don't know why this is.我创建了一个新的类来扩展JTable来测试它。我从JTable源复制了getScrollableUnitIncrement的代码,并添加了print语句。传递的方向似乎总是SwingConstants.VERTICAL,而在默认的外观(Mac Aqua或其他)中,水平和垂直滚动都有效。我不知道为什么会这样。
-
Another part of the project also relies on horizontal scrolling. I tested it with both LaFs, and it worked fine in the default, but Nimbus would not allow me to scroll horizontally, either.
该项目的另一部分还依赖于水平滚动。我用两个LaF测试了它,它在默认情况下工作正常,但Nimbus也不允许我水平滚动。
Could this be a bug with Nimbus?
这可能是Nimbus的错误吗?
Either way, I guess I'm going to use a different Look and Feel...
无论哪种方式,我想我将使用不同的外观和感觉......
EDIT #2:
I should have mentioned this before. I am able to scroll horizontally with the scroll bar in the window, but not with my track pad or scroll wheel on my mouse.
我之前应该提到这一点。我可以使用窗口中的滚动条水平滚动,但不能使用鼠标上的滚轮或滚轮。
2 个解决方案
#1
3
(Note: After writing this, I found a solution, which appears in the addendum of this post.)
(注意:写完之后,我找到了一个解决方案,该解决方案出现在本文的附录中。)
To reproduce the problem, you need to make the scroll bars required. (This is why some people have trouble reproducing this bug.) This means the obvious workaround is to make your horizontal scroll bar optional. (This is not always practical.)
要重现该问题,您需要使滚动条成为必需。 (这就是为什么有些人无法再现这个bug。)这意味着明显的解决方法是使你的水平滚动条可选。 (这并不总是实用的。)
You will only see the bug when you drag the window's width out to more than 1200 pixels or so. Until then, the scroll bar will work fine.
只有在将窗口宽度拖动到1200像素左右时,才会看到错误。在此之前,滚动条将正常工作。
And the problem only shows up in Nimbus. (It may show up in other L&Fs created from the SynthLookAndFeel, but I haven't investigated that yet.)
而这个问题只出现在Nimbus上。 (它可能出现在从SynthLookAndFeel创建的其他L&F中,但我还没有调查过。)
I've found that the spurious scroll bar thumb only shows up when you have no need to scroll, so it's just a visual bug. When you need to scroll, the scroll bar thumb will appear and will work properly, although it might not be the right size. This may be why it hasn't been fixed yet.
我发现当你不需要滚动时,虚假的滚动条拇指只显示出来,所以这只是一个视觉错误。当您需要滚动时,滚动条拇指将出现并且将正常工作,尽管它可能不是正确的尺寸。这可能是它尚未修复的原因。
Here's an example where you can compare the different L&Fs. In this example, Choose Nimbus, then drag the width inward and watch how the size of the scroll bar changes. When you're wider than the background image, the spurious scroll bar will be visible. As soon as you get narrower, a valid scroll bar thumb will appear, but it will be a bit too small. As you get smaller, the scroll bar thumb will stay a constant size until you reach a certain point, (at viewport width of 1282 pixels) then it will start getting smaller like it's supposed to.
这是一个可以比较不同L&F的例子。在此示例中,选择Nimbus,然后向内拖动宽度并观察滚动条的大小如何变化。当您比背景图像宽时,将显示虚假滚动条。一旦变窄,就会出现一个有效的滚动条拇指,但它会有点太小。当你变小时,滚动条拇指将保持恒定的大小,直到你到达某个点,(在视口宽度为1282像素)然后它将开始变小,就像它应该的那样。
With any other L&F, as soon as you get narrower than the background image, a thumb will appear that almost fills its space. It gets smaller as the window gets smaller, like it's supposed to.
对于任何其他L&F,只要你比背景图像更窄,就会出现一个几乎填满其空间的拇指。随着窗口变小,它变得越来越小,就像它应该的那样。
(This exercise will also reveal how Nimbus draws much more slowly than any other L&F.)
(这个练习还将揭示Nimbus如何比任何其他L&F吸引得慢得多。)
You can observe different, but still incorrect behavior by making the icon smaller. Try 800 x 450. The spurious scroll bar will appear when the viewport width is > 1035. (Viewport size is shown at the bottom of the window.)
您可以通过缩小图标来观察不同但仍然不正确的行为。尝试800 x 450.当视口宽度> 1035时,将出现虚假滚动条。(视口大小显示在窗口底部。)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* NimbusScrollBug
* <p/>
* @author Miguel Muñoz
*/
public class NimbusScrollBug extends JPanel {
private static final long serialVersionUID = -4235866781219951631L;
private static JFrame frame;
private static boolean firstTime = true;
private static Point location;
private static final UIManager.LookAndFeelInfo[] INFOS
= UIManager.getInstalledLookAndFeels();
private final JLabel viewPortLabel = new JLabel();
public static void main(final String[] args) {
makeMainFrame(new NimbusScrollBug(), "System");
}
public static void makeMainFrame(final NimbusScrollBug mainPanel,
final String name) {
if (firstTime) {
installLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
frame = new JFrame(name);
final Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(mainPanel, BorderLayout.CENTER);
contentPane.add(makeButtonPane(mainPanel), BorderLayout.LINE_START);
frame.setLocationByPlatform(firstTime);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
if (firstTime) {
location = frame.getLocation();
} else {
frame.setLocation(location);
}
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(final ComponentEvent e) {
location = e.getComponent().getLocation();
}
});
firstTime = false;
}
private static JPanel makeButtonPane(final NimbusScrollBug mainPanel) {
JPanel innerButtonPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 0; // forces vertical layout.
for (final UIManager.LookAndFeelInfo lAndF : INFOS) {
final JButton button = new JButton(lAndF.getName());
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
frame.dispose();
installLookAndFeel(lAndF.getClassName());
makeMainFrame(new NimbusScrollBug(), lAndF.getName());
}
});
innerButtonPanel.add(button, constraints);
}
final String version = System.getProperty("java.version");
JLabel versionLabel = new JLabel("Java Version " + version);
innerButtonPanel.add(versionLabel, constraints);
JPanel outerButtonPanel = new JPanel(new BorderLayout());
outerButtonPanel.add(innerButtonPanel, BorderLayout.PAGE_START);
return outerButtonPanel;
}
private static void installLookAndFeel(final String className) {
//noinspection OverlyBroadCatchBlock
try {
UIManager.setLookAndFeel(className);
} catch (Exception e) {
//noinspection ProhibitedExceptionThrown
throw new RuntimeException(e);
}
}
private NimbusScrollBug() {
Icon icon = new Icon() {
@Override
public void paintIcon(final Component c, final Graphics g,
final int x, final int y) {
Graphics2D g2 = (Graphics2D) g;
g2.translate(x, y);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Stroke lineStroke = new BasicStroke(6.0f);
g2.setStroke(lineStroke);
g2.setColor(Color.white);
g2.fillRect(0, 0, getIconWidth(), getIconHeight());
g2.setColor(Color.RED);
g2.drawLine(0, 0, getIconWidth(), getIconHeight());
g2.drawLine(0, getIconHeight(), getIconWidth(), 0);
g2.dispose();
}
@Override
public int getIconWidth() {
return 1600;
}
@Override
public int getIconHeight() {
return 900;
}
};
JLabel label = new JLabel(icon);
setLayout(new BorderLayout());
final JScrollPane scrollPane = new JScrollPane(label,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
label.addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
@Override
public void ancestorResized(final HierarchyEvent e) {
viewPortLabel.setText("ViewPort Size: "
+ scrollPane.getViewport().getSize());
}
});
add(scrollPane, BorderLayout.CENTER);
add(viewPortLabel, BorderLayout.PAGE_END);
}
}
Addendum: Further investigation revealed the problem. The NimbusDefaults class, which creates the UIDefaults instance for Nimbus, has this line:
附录:进一步调查显示了这个问题。为Nimbus创建UIDefaults实例的NimbusDefaults类具有以下特性:
d.put("ScrollBar.maximumThumbSize", new DimensionUIResource(1000, 1000));
Any other look and feel uses 4096 for both values (so, for really big monitors, they will show the same behavior).
任何其他外观都使用4096两个值(因此,对于非常大的显示器,它们将显示相同的行为)。
The following method, which may be used to install any look and feel, will fix this problem:
以下方法可用于安装任何外观,将解决此问题:
private static void installLookAndFeel(final String className) {
//noinspection OverlyBroadCatchBlock
try {
Class<?> lnfClass = Class.forName(className, true,
Thread.currentThread().getContextClassLoader());
final LookAndFeel lAndF;
lAndF = (LookAndFeel) lnfClass.getConstructor().newInstance();
// Reset the defaults after instantiating, but before
// calling UIManager.setLookAndFeel(). This fixes the Nimbus bug
DimensionUIResource dim = new DimensionUIResource(4096, 4096);
lAndF.getDefaults().put("ScrollBar.maximumThumbSize", dim);
UIManager.setLookAndFeel(lAndF);
} catch (Exception e) {
final String systemName = UIManager.getSystemLookAndFeelClassName();
// Prevents an infinite recursion that's not very likely...
// (I like to code defensively)
if (!className.equals(systemName)) {
installLookAndFeel(systemName);
} else {
// Feel free to handle this any other way.
//noinspection ProhibitedExceptionThrown
throw new RuntimeException(e);
}
}
}
Of course, you can fix the problem for really big monitors by using a bigger value.
当然,您可以通过使用更大的值来解决真正大型显示器的问题。
I confirmed that the vertical scroll bar has exactly the same problem, but is only seen when the window gets very large vertically. This is why this problem is usually only seen with the horizontal scroll bar.
我确认垂直滚动条有完全相同的问题,但仅在窗口垂直变大时才能看到。这就是为什么这个问题通常只能在水平滚动条中看到的原因。
#2
0
Based on the information you provided, I'm not able to recreate your problem (and therefore not able to help you figure out what's going wrong). Here's a sscce that works for me. Can you reproduce the problem with this example? Perhaps the problem is trickling down from a different part of the application.
根据您提供的信息,我无法重现您的问题(因此无法帮助您弄清楚出了什么问题)。这是一个适合我的sscce。你能用这个例子重现这个问题吗?也许问题是从应用程序的不同部分流下来。
public static void main(String[] args){
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
//Create Frame
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create Table
JTable table = new JTable(0, 2);
((DefaultTableModel) table.getModel()).addRow(new Object[]{"Sample Text", "Hi Mom!"});
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Wrap table in Scroll pane and add to frame
frame.add(new JScrollPane(table), BorderLayout.CENTER);
// Finish setting up the frame and display
frame.setBounds(0, 0, 600,400);
frame.setPreferredSize(new Dimension(600, 400));
frame.pack();
frame.setVisible(true);
}
#1
3
(Note: After writing this, I found a solution, which appears in the addendum of this post.)
(注意:写完之后,我找到了一个解决方案,该解决方案出现在本文的附录中。)
To reproduce the problem, you need to make the scroll bars required. (This is why some people have trouble reproducing this bug.) This means the obvious workaround is to make your horizontal scroll bar optional. (This is not always practical.)
要重现该问题,您需要使滚动条成为必需。 (这就是为什么有些人无法再现这个bug。)这意味着明显的解决方法是使你的水平滚动条可选。 (这并不总是实用的。)
You will only see the bug when you drag the window's width out to more than 1200 pixels or so. Until then, the scroll bar will work fine.
只有在将窗口宽度拖动到1200像素左右时,才会看到错误。在此之前,滚动条将正常工作。
And the problem only shows up in Nimbus. (It may show up in other L&Fs created from the SynthLookAndFeel, but I haven't investigated that yet.)
而这个问题只出现在Nimbus上。 (它可能出现在从SynthLookAndFeel创建的其他L&F中,但我还没有调查过。)
I've found that the spurious scroll bar thumb only shows up when you have no need to scroll, so it's just a visual bug. When you need to scroll, the scroll bar thumb will appear and will work properly, although it might not be the right size. This may be why it hasn't been fixed yet.
我发现当你不需要滚动时,虚假的滚动条拇指只显示出来,所以这只是一个视觉错误。当您需要滚动时,滚动条拇指将出现并且将正常工作,尽管它可能不是正确的尺寸。这可能是它尚未修复的原因。
Here's an example where you can compare the different L&Fs. In this example, Choose Nimbus, then drag the width inward and watch how the size of the scroll bar changes. When you're wider than the background image, the spurious scroll bar will be visible. As soon as you get narrower, a valid scroll bar thumb will appear, but it will be a bit too small. As you get smaller, the scroll bar thumb will stay a constant size until you reach a certain point, (at viewport width of 1282 pixels) then it will start getting smaller like it's supposed to.
这是一个可以比较不同L&F的例子。在此示例中,选择Nimbus,然后向内拖动宽度并观察滚动条的大小如何变化。当您比背景图像宽时,将显示虚假滚动条。一旦变窄,就会出现一个有效的滚动条拇指,但它会有点太小。当你变小时,滚动条拇指将保持恒定的大小,直到你到达某个点,(在视口宽度为1282像素)然后它将开始变小,就像它应该的那样。
With any other L&F, as soon as you get narrower than the background image, a thumb will appear that almost fills its space. It gets smaller as the window gets smaller, like it's supposed to.
对于任何其他L&F,只要你比背景图像更窄,就会出现一个几乎填满其空间的拇指。随着窗口变小,它变得越来越小,就像它应该的那样。
(This exercise will also reveal how Nimbus draws much more slowly than any other L&F.)
(这个练习还将揭示Nimbus如何比任何其他L&F吸引得慢得多。)
You can observe different, but still incorrect behavior by making the icon smaller. Try 800 x 450. The spurious scroll bar will appear when the viewport width is > 1035. (Viewport size is shown at the bottom of the window.)
您可以通过缩小图标来观察不同但仍然不正确的行为。尝试800 x 450.当视口宽度> 1035时,将出现虚假滚动条。(视口大小显示在窗口底部。)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* NimbusScrollBug
* <p/>
* @author Miguel Muñoz
*/
public class NimbusScrollBug extends JPanel {
private static final long serialVersionUID = -4235866781219951631L;
private static JFrame frame;
private static boolean firstTime = true;
private static Point location;
private static final UIManager.LookAndFeelInfo[] INFOS
= UIManager.getInstalledLookAndFeels();
private final JLabel viewPortLabel = new JLabel();
public static void main(final String[] args) {
makeMainFrame(new NimbusScrollBug(), "System");
}
public static void makeMainFrame(final NimbusScrollBug mainPanel,
final String name) {
if (firstTime) {
installLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
frame = new JFrame(name);
final Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(mainPanel, BorderLayout.CENTER);
contentPane.add(makeButtonPane(mainPanel), BorderLayout.LINE_START);
frame.setLocationByPlatform(firstTime);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
if (firstTime) {
location = frame.getLocation();
} else {
frame.setLocation(location);
}
frame.addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(final ComponentEvent e) {
location = e.getComponent().getLocation();
}
});
firstTime = false;
}
private static JPanel makeButtonPane(final NimbusScrollBug mainPanel) {
JPanel innerButtonPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 0; // forces vertical layout.
for (final UIManager.LookAndFeelInfo lAndF : INFOS) {
final JButton button = new JButton(lAndF.getName());
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
frame.dispose();
installLookAndFeel(lAndF.getClassName());
makeMainFrame(new NimbusScrollBug(), lAndF.getName());
}
});
innerButtonPanel.add(button, constraints);
}
final String version = System.getProperty("java.version");
JLabel versionLabel = new JLabel("Java Version " + version);
innerButtonPanel.add(versionLabel, constraints);
JPanel outerButtonPanel = new JPanel(new BorderLayout());
outerButtonPanel.add(innerButtonPanel, BorderLayout.PAGE_START);
return outerButtonPanel;
}
private static void installLookAndFeel(final String className) {
//noinspection OverlyBroadCatchBlock
try {
UIManager.setLookAndFeel(className);
} catch (Exception e) {
//noinspection ProhibitedExceptionThrown
throw new RuntimeException(e);
}
}
private NimbusScrollBug() {
Icon icon = new Icon() {
@Override
public void paintIcon(final Component c, final Graphics g,
final int x, final int y) {
Graphics2D g2 = (Graphics2D) g;
g2.translate(x, y);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Stroke lineStroke = new BasicStroke(6.0f);
g2.setStroke(lineStroke);
g2.setColor(Color.white);
g2.fillRect(0, 0, getIconWidth(), getIconHeight());
g2.setColor(Color.RED);
g2.drawLine(0, 0, getIconWidth(), getIconHeight());
g2.drawLine(0, getIconHeight(), getIconWidth(), 0);
g2.dispose();
}
@Override
public int getIconWidth() {
return 1600;
}
@Override
public int getIconHeight() {
return 900;
}
};
JLabel label = new JLabel(icon);
setLayout(new BorderLayout());
final JScrollPane scrollPane = new JScrollPane(label,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
label.addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
@Override
public void ancestorResized(final HierarchyEvent e) {
viewPortLabel.setText("ViewPort Size: "
+ scrollPane.getViewport().getSize());
}
});
add(scrollPane, BorderLayout.CENTER);
add(viewPortLabel, BorderLayout.PAGE_END);
}
}
Addendum: Further investigation revealed the problem. The NimbusDefaults class, which creates the UIDefaults instance for Nimbus, has this line:
附录:进一步调查显示了这个问题。为Nimbus创建UIDefaults实例的NimbusDefaults类具有以下特性:
d.put("ScrollBar.maximumThumbSize", new DimensionUIResource(1000, 1000));
Any other look and feel uses 4096 for both values (so, for really big monitors, they will show the same behavior).
任何其他外观都使用4096两个值(因此,对于非常大的显示器,它们将显示相同的行为)。
The following method, which may be used to install any look and feel, will fix this problem:
以下方法可用于安装任何外观,将解决此问题:
private static void installLookAndFeel(final String className) {
//noinspection OverlyBroadCatchBlock
try {
Class<?> lnfClass = Class.forName(className, true,
Thread.currentThread().getContextClassLoader());
final LookAndFeel lAndF;
lAndF = (LookAndFeel) lnfClass.getConstructor().newInstance();
// Reset the defaults after instantiating, but before
// calling UIManager.setLookAndFeel(). This fixes the Nimbus bug
DimensionUIResource dim = new DimensionUIResource(4096, 4096);
lAndF.getDefaults().put("ScrollBar.maximumThumbSize", dim);
UIManager.setLookAndFeel(lAndF);
} catch (Exception e) {
final String systemName = UIManager.getSystemLookAndFeelClassName();
// Prevents an infinite recursion that's not very likely...
// (I like to code defensively)
if (!className.equals(systemName)) {
installLookAndFeel(systemName);
} else {
// Feel free to handle this any other way.
//noinspection ProhibitedExceptionThrown
throw new RuntimeException(e);
}
}
}
Of course, you can fix the problem for really big monitors by using a bigger value.
当然,您可以通过使用更大的值来解决真正大型显示器的问题。
I confirmed that the vertical scroll bar has exactly the same problem, but is only seen when the window gets very large vertically. This is why this problem is usually only seen with the horizontal scroll bar.
我确认垂直滚动条有完全相同的问题,但仅在窗口垂直变大时才能看到。这就是为什么这个问题通常只能在水平滚动条中看到的原因。
#2
0
Based on the information you provided, I'm not able to recreate your problem (and therefore not able to help you figure out what's going wrong). Here's a sscce that works for me. Can you reproduce the problem with this example? Perhaps the problem is trickling down from a different part of the application.
根据您提供的信息,我无法重现您的问题(因此无法帮助您弄清楚出了什么问题)。这是一个适合我的sscce。你能用这个例子重现这个问题吗?也许问题是从应用程序的不同部分流下来。
public static void main(String[] args){
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
}
//Create Frame
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create Table
JTable table = new JTable(0, 2);
((DefaultTableModel) table.getModel()).addRow(new Object[]{"Sample Text", "Hi Mom!"});
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Wrap table in Scroll pane and add to frame
frame.add(new JScrollPane(table), BorderLayout.CENTER);
// Finish setting up the frame and display
frame.setBounds(0, 0, 600,400);
frame.setPreferredSize(new Dimension(600, 400));
frame.pack();
frame.setVisible(true);
}