My problem is that I need to make a GUI that, on startup, displays a login screen, then, when the user succesfully logs in, displays a different screen. I've visited other questions on both this board and on others, and on all of them, the general consensus is that instead of using two different, JFrames, I should use 2 JPanels in the same JFrame. When a user logs in, the first JFrame, asking for log in details, will have its visibility set to false and the second JFrame's visibility will become True. The problem I'm having here is that I can't seem to place 2 JPanels on the same location. I'm using Jigloo to work on Swing. Whenever I place the second JPanel and set its visibility to false, it's size becomes 0,0. I tried putting components on the second panel, then setting my preferred size and then switching the visibility to false, but both panels disappeared during executionm despite the first frame's visibility still being true and being the proper size. Help please!
I've answered a similar question wherein you've multiple panels within single JFrame.. and based on user action performed panels are replaced
Can't seem to get .remove to work
To skin the program based on your query:
public class Main extends JFrame implements ActionListener
{
private JPanel componentPanel = null;
private JPanel loginPanel = null;
private JLabel loginLabel = null;
private JPanel optionPanel = null;
private JLabel optionLabel = null;
private JButton loginButton = null;
public JPanel getComponentPanel()
{
if(null == componentPanel)
{
componentPanel = new JPanel();
GridBagLayout gridBagLayout = new GridBagLayout();
componentPanel.setLayout(gridBagLayout);
GridBagConstraints constraint = new GridBagConstraints();
constraint.insets = new Insets(10, 10, 10, 10);
loginPanel = new JPanel();
constraint.gridx = 0;
constraint.gridy = 0;
loginPanel.setMinimumSize(new Dimension(100, 50));
loginPanel.setPreferredSize(new Dimension(100, 50));
loginPanel.setMaximumSize(new Dimension(100, 50));
loginPanel.setBorder(
BorderFactory.createLineBorder(Color.RED));
loginLabel = new JLabel("Login Panel");
loginPanel.add(loginLabel);
componentPanel.add(loginPanel, constraint);
optionPanel = new JPanel();
constraint.gridx = 0;
constraint.gridy = 0;
optionPanel.setMinimumSize(new Dimension(100, 50));
optionPanel.setPreferredSize(new Dimension(100, 50));
optionPanel.setMaximumSize(new Dimension(100, 50));
optionPanel.setBorder(
BorderFactory.createLineBorder(Color.BLUE));
optionLabel = new JLabel("Option Panel");
optionPanel.add(optionLabel);
componentPanel.add(optionPanel, constraint);
loginButton = new JButton("Login");
constraint.gridx = 0;
constraint.gridy = 1;
loginButton.addActionListener(this);
componentPanel.add(loginButton, constraint);
}
return componentPanel;
}
public void actionPerformed (ActionEvent evt)
{
loginPanel.setVisible(false);
loginButton.setEnabled(false);
optionPanel.setVisible(true);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
Main main = new Main();
frame.setTitle("Simple example");
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setContentPane(main.getComponentPanel());
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Related
I'm currently working on a project for my studies and I have a little problem concerning the GUI.
Here is some code:
private JButton zoomUp, zoomDown;
private JComboBox fractalList;
private JLabel choice,space;
private JPanel ui,display;
private JFrame window;
public FractalView(FractalModel m, FractalController c, String title, int size_X, int size_Y)
{
window =new JFrame();
window.setTitle(title);
window.setSize(size_X,size_Y);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor=GridBagConstraints.FIRST_LINE_START;
ui=new JPanel();
ui.setBackground(Color.GRAY);
ui.setBorder(BorderFactory.createTitledBorder("Interface de Controle et Options"));
BoxLayout uiLayout = new BoxLayout(ui, BoxLayout.PAGE_AXIS);
ui.setLayout(uiLayout);
ui.setMaximumSize(ui.getPreferredSize());
zoomUp = new JButton("Zoom +");
zoomUp.setAlignmentX(LEFT_ALIGNMENT);
zoomUp.setBorder(BorderFactory.createLineBorder(Color.RED));
ui.add(zoomUp);
zoomDown = new JButton("Zoom -");
//ui.add(zoomDown);
choice = new JLabel("Choisir une fractale : ");
//ui.add(choice);
Object[] elements = new Object[]{"Mandelbrot", "Julia", "Buddhabrot"};
fractalList = new JComboBox<Object>(elements);
//fractalList.setBorder(BorderFactory.createLineBorder(Color.RED));
fractalList.setAlignmentX(LEFT_ALIGNMENT);
fractalList.setMaximumSize(new Dimension(Short.MAX_VALUE,20));
//ui.add(fractalList);
gbc.weighty=1;
gbc.ipadx=300;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.VERTICAL;
gbc.gridx=0;
gbc.gridy=0;
window.add(ui,gbc);
display=new JPanel();
display.setBackground(Color.RED);
gbc.weightx=1;
gbc.gridheight=1;
gbc.gridwidth=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.gridx=1;
gbc.gridy=0;
window.add(display,gbc);
window.setVisible(true);
}
The problem comes from JPanel ui . As long it is empty the size is as desired. But when I add any component to it it's weight increases.
I tried to use setMaxSize() but even though it gets resized and this could cause problem with what I want to display on JPanel display. I would prefer to avoid using GridBagLayout again.
Does someone have an idea?
If you just want to split the Frame and don't want to fight with GridBagLayout, you could just use a BorderLayout.
Then, add one panel to BorderLayout.WEST and the other one to the BorderLayout.EAST position. And remember to call setPreferredSize to fix your desired width and height.
I've made some changes to your code. Check it out:
public class TestFrame {
private JButton zoomUp, zoomDown;
private JComboBox fractalList;
private JLabel choice, space;
private JPanel ui, display;
private JFrame window;
public TestFrame(String title, int size_X, int size_Y) {
window = new JFrame();
window.setTitle(title);
window.setSize(size_X, size_Y);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setLayout(new BorderLayout());
ui = new JPanel();
ui.setPreferredSize(new Dimension(size_X/2,size_Y));
ui.setBackground(Color.GRAY);
ui.setBorder(BorderFactory.createTitledBorder("Interface de Controle et Options"));
BoxLayout uiLayout = new BoxLayout(ui, BoxLayout.PAGE_AXIS);
ui.setLayout(uiLayout);
zoomUp = new JButton("Zoom +");
// zoomUp.setAlignmentX(LEFT_ALIGNMENT);
zoomUp.setBorder(BorderFactory.createLineBorder(Color.RED));
ui.add(zoomUp);
zoomDown = new JButton("Zoom -");
ui.add(zoomDown);
choice = new JLabel("Choisir une fractale : ");
ui.add(choice);
Object[] elements = new Object[] { "Mandelbrot", "Julia", "Buddhabrot" };
fractalList = new JComboBox<Object>(elements);
// fractalList.setBorder(BorderFactory.createLineBorder(Color.RED));
// fractalList.setAlignmentX(LEFT_ALIGNMENT);
fractalList.setMaximumSize(new Dimension(Short.MAX_VALUE, 20));
ui.add(fractalList);
window.add(ui, BorderLayout.WEST);
display = new JPanel();
display.setBackground(Color.RED);
display.setPreferredSize(new Dimension(size_X/2,size_Y));
window.add(display, BorderLayout.EAST);
window.setVisible(true);
}
public static void main(String[] args) {
new TestFrame("test of BorderLayout with WEST and EAST", 800, 600);
}
}
If you need something more complex than that, you could go with miglayout.
I am having issue where my JPanel is not setting up the size. I am not sure if is something to do with my JTab or JFrame. I am using GridBagLayout layout management. And for some reason are not able to set the size.
Here is a dummy code, following the same logic to my original source code:
FirstPanel.java
import javax.swing.*;
import java.awt.*;
public class FirstPanel extends JPanel {
private JLabel label1 = new JLabel("Label 1");
private JTextField textField1 = new JTextField();
private GridBagConstraints c = new GridBagConstraints();
public FirstPanel() {
//Size is not overriding
Dimension size = getPreferredSize();
size.width = 100;
setPreferredSize(size);
setBorder(BorderFactory.createTitleBorder("Border Title");
setLayout(new GridBagLayout());
addComponents();
}
private void addComponents() {
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.insets = new Insets(5, 0, 0, 0);
add(label1, c);
c.gridx = 1;
add(textField1, c);
c.weightx = 1;
c.weighty = 1;
add(new JLabel(""), c);
}
}
MainPanel.java
import javax.swing.*;
import java.awt.*;
public class MainPanel {
private JFrame frame = new JFrame("App");
private JPanel panel1 = new JPanel(new GridBagLayout());
private GridBagConstraints c = new GridBagConstraints();
private JTabbedPane tabPane = new JTabbedPane();
public MainPanel() {
addComponents();
frame.add(tabPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 350);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
}
private void addComponents() {
tabPane.addTab("Tab 1", new FirstPanel());
}
}
Main.java
public class Main {
public static void main(String[] args) {
new MainPanel();
}
}
Or at least have two JPanels,
Exactly.
Frist you create a main panel using a BorderLayout that you add to the tabbed pane.
Then you have a second panel for your labels and text fields (using whatever layout manager you want). Then you add this panel to the BorderLayout.LINE_START.
Then you add your scrollpane containing the JTable to the BorderLayout.CENTER of the main panel.
Read the tutorial on Layout Manager. Nest panels with different layout managers as required.
want to have JTable taking 50% of the other side.
Picking a random number like 50% is not the way to design a GUI. What happens if the frame is made smaller/larger. What happens to the space? Design the layout with flexibility in mind, just like your browser window is designed. There are always fixed areas where the size is determined by the components added and there is a flexible area that grows/shrinks as desired.
I'm working with GUI in Java and I've made several JDialogs opening one above the other.
I tried to create a JTabbedPane and I have succeed. However, I have to make the JTabbedPane in a JFrame. I've tried but the JPanel opens all blank.
Second of all when I use JFrame (so the new JTabbedPane became operational) that same frame appears behind the previous one.
So my questions are:
How can I create the tabbed pane in a JDialog ?
How do I make the JTabbedPane appear in front of all other frames, if I use JFrame ?
Here's my code, this JFrame opened when I click on a JButton from a previous JDialog
public class AddComponents extends JDialog {
private String[] arr = {"House", "Microgrid", "CSP", "VPP"};
public AddComponents(JDialog pai, String titulo)
{
super(pai, titulo);
frame = new JFrame(titulo);
// Display the window.
frame.setSize(500, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set grid layout for the frame
frame.getContentPane().setLayout(new GridLayout(1, 1));
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
pack();
for (int i = 0; i < arr.length; i++) {
String tmp = arr[i];
tabbedPane.addTab(tmp, makePanel(tmp));
}
frame.getContentPane().add(tabbedPane);
frame.setMinimumSize(new Dimension(getWidth(), getHeight()));
frame.setLocation(pai.getX() + 85, pai.getY() + 25);
frame.setEnabled(true);
}
private JPanel makePanel(String text) {
JPanel p = new JPanel();
//p.setLayout(new GridLayout(0,1));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
if(text.equals("House"))
{ //CADA UM DOS ifs chama a class correspondente para criar o interface
p1.setLayout(new GridLayout(4, 2));
idLabel = new JLabel("Component ID:");
idText = new JTextField("");
p1.add(idLabel);
p1.add(idText);
maxUsageLabel = new JLabel("Max usage per hour:");
maxUsageText = new JTextField("");
p1.add(maxUsageLabel);
p1.add(maxUsageText);
minUsageLabel = new JLabel("Min usage per hour:");
minUsageText = new JTextField("");
p1.add(minUsageLabel);
p1.add(minUsageText);
averageUsageLabel = new JLabel("Average usage per hour:");
averageUsageText = new JTextField("");
p1.add(averageUsageLabel);
p1.add(averageUsageText);
// emptyLabel = new JLabel("");
saveButton = new JButton("Save");
// p.add(emptyLabel);
p2.add(saveButton);
p.add(p1);
p.add(p2);
}
if(text.equals("Microgrid"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" Microgrid");
p.add(outroLabel);
}
if(text.equals("VPP"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" VPP");
p.add(outroLabel);
}
if(text.equals("CSP"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" CSP");
p.add(outroLabel);
}
return p;
}
}
"How can I create the tabbed pane in a JDialog ?"
same as you would if you added it to a JFrame. There is essentially no difference here whatsoever.
"How do I make the JTabbedPane appear in front of all other frames, if I use JFrame ?"
you don't. You use a JDialog if you want to display a window above other windows.
For creating the JDialog use:
final JDialog dialog = new JDialog();
dialog.add(tabbedPane);
dialog.setVisible(true);
Java applications normally have only one JFrame, so nobody worries about the Z-order. If you like them, you can use JInternalFrame. Here is the tutorial. You can, however, use dialogs instead.
this is my first time here.
I was writing a GUI-driven program which would allow me to perform Caesar's cipher on .txt files.
However, before I could add the ActionListeners and ChangeListeners I decided to test the GUI. Here is what I got:
Here is the code:
package implementation;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Frame extends JFrame{
public Frame(){
super("Caesar[E]");
this.setVisible(true);
this.setLocationRelativeTo(null);
/*Adding the options to GUI*/
factor.setPreferredSize(new Dimension(30,30));
JToolBar toolbar = new JToolBar();
radio.add(encrypt);
radio.add(decrypt);
toolbar.add(encrypt);
toolbar.add(decrypt);
toolbar.add(factor);
toolbar.setFloatable(false);
/*Adding the JTextArea for input*/
Box inputBound = Box.createHorizontalBox();
Box inputBound_text = Box.createVerticalBox();
Box inputBound_buttons = Box.createVerticalBox();
inputScroll.add(input);
inputScroll.setEnabled(true);
input.setEditable(true);
inputScroll.setBorder(BorderFactory.createTitledBorder("Text/File for Encryption/" +
"Decryption"));
inputBound_text.add(inputScroll);
inputBound_buttons.add(openFile);
inputBound_buttons.add(cancelFileInput);
inputBound.add(inputBound_text);
inputBound.add(Box.createHorizontalStrut(25));
inputBound.add(inputBound_buttons);
/*Adding JTextArea for output*/
Box outputBound = Box.createHorizontalBox();
Box outputBound_text = Box.createVerticalBox();
Box outputBound_buttons = Box.createVerticalBox();
outputScroll.add(output);
output.setEditable(true);
outputScroll.setBorder(BorderFactory.createTitledBorder("Text After Encryption" +
"/Decryption"));
outputBound_text.add(outputScroll);
outputBound_buttons.add(saveFile);
outputBound_buttons.add(send);
outputBound.add(outputBound_text);
outputBound.add(Box.createHorizontalStrut(25));
outputBound.add(outputBound_buttons);
outputBound.setSize(150, 200);
/*Adding JButton for performing the action*/
this.add(performAction,BorderLayout.SOUTH);
/*Adding the components to the Frame*/
Box outerBox = Box.createVerticalBox();
outerBox.add(toolbar,BorderLayout.NORTH);
outerBox.add(inputBound);
outerBox.add(outputBound);
this.add(outerBox);
this.setSize(500, 700);
}
boolean isFileInput = false;
boolean isEncrypt = true;
JButton performAction = new JButton("Encrypt!");
JButton openFile = new JButton("Open a File");
JButton cancelFileInput = new JButton("Cancel File Input");
JButton saveFile = new JButton("Save File");
JButton send = new JButton("Send");
JTextArea input = new JTextArea();
JTextArea output = new JTextArea();
JFileChooser chooser = new JFileChooser();
JScrollPane inputScroll = new JScrollPane();
JScrollPane outputScroll = new JScrollPane();
ButtonGroup radio = new ButtonGroup();
JRadioButton encrypt = new JRadioButton("Encrypt",true);
JRadioButton decrypt = new JRadioButton("Decrypt",false);
JSpinner factor = new JSpinner(new SpinnerNumberModel(1,1,26,1));
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
new Frame();
}
});
}
}
Can you please tell me how I can solve the problems as shown in the image?
I know I can use setPreferredSize() but how do I make sure that I enter the correct dimension without trial-and-error?
I like the SpringLayout, it is very flexible and there is very not a lot that it can't do. Especially you will not need to care about setPreferredSize anymore. Just search for it, there are enough resources out there.
SpringLayout allows you to define the size of elements relative to others - so for example, you can make sure the buttons will look the same.
I would recommend MiGLayout as LayoutManager. Things like that are easy in MiGLayout
Trial-and-error is never a good way to get the layout you want. Instead, use the JTextArea constructor that lets you say how many rows and columns you want.
JTextArea(int rows, int columns)
JTextArea will calculate a good preferred size for when you pack() the window, and you won't need setSize().
Edit: You said, "JTextArea is inactive. I can't enter text in it."
Instead of add(), use setViewportView():
inputScroll.setViewportView(input);
...
outputScroll.setViewportView(output);
...
In situations like these, I like to divide my application into areas of responsibility. This keeps the code clean and self contained, allowing me to replace sections of it if/and when required, without adversely effect the rest of the application.
It also means that you can focus on the individual requirements of each section.
With complex layout, it's always better (IMHO) to use compounding containers with separate layout managers, it reduces the complexity and potential for strange cross over behavior.
public class BadLayout07 {
public static void main(String[] args) {
new BadLayout07();
}
public BadLayout07() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MasterPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MasterPane extends JPanel {
public MasterPane() {
EncryptSettings encryptSettings = new EncryptSettings();
InputPane inputPane = new InputPane();
OutputPane outputPane = new OutputPane();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(encryptSettings, gbc);
gbc.gridy++;
gbc.weighty = 1;
gbc.fill = gbc.BOTH;
add(inputPane, gbc);
gbc.gridy++;
add(outputPane, gbc);
}
}
public class EncryptSettings extends JPanel {
private JRadioButton encrypt;
private JRadioButton decrypt;
private JSpinner factor;
public EncryptSettings() {
encrypt = new JRadioButton("Encrypt");
decrypt = new JRadioButton("Decrypt");
ButtonGroup bg = new ButtonGroup();
bg.add(encrypt);
bg.add(decrypt);
factor = new JSpinner(new SpinnerNumberModel(new Integer(1), new Integer(1), null, new Integer(1)));
setLayout(new FlowLayout(FlowLayout.LEFT));
add(encrypt);
add(decrypt);
add(factor);
}
}
public class InputPane extends JPanel {
private JTextArea input;
private JButton open;
private JButton close;
public InputPane() {
setBorder(new TitledBorder("Source Text"));
input = new JTextArea();
open = new JButton("Open");
close = new JButton("Close");
JPanel tb = new JPanel(new FlowLayout(FlowLayout.LEFT));
tb.add(open);
tb.add(close);
setLayout(new BorderLayout());
add(tb, BorderLayout.NORTH);
add(new JScrollPane(input));
}
}
public class OutputPane extends JPanel {
private JTextArea output;
private JButton save;
private JButton send;
public OutputPane() {
setBorder(new TitledBorder("Encrypted Text"));
output = new JTextArea();
output.setEditable(false);
save = new JButton("Save");
send = new JButton("Send");
JPanel tb = new JPanel(new FlowLayout(FlowLayout.LEFT));
tb.add(save);
tb.add(send);
setLayout(new BorderLayout());
add(tb, BorderLayout.NORTH);
add(new JScrollPane(output));
}
}
}
I've not interconnect any of the functionality, but it is a simple case of providing appropriate setters and getters as required, as well appropriate event listeners.
i have to writing an applet, in left side i must use an panel to contain a list of vehicles that can be a list of buttons,what is the problem, number of the vehicles are not given !!!
so, i need to scrolling panel when number of vehicles is too much,
i do this for jframe, but it didn't work correct with panel, please help me with an example
the code i use to scrolling panel is :
public class VehicleList extends JPanel {
private ArrayList<VehicleReport> vehicles;
private ArrayList<JButton> v_buttons = new ArrayList<JButton>();
public void showList(ArrayList<Vehicles> vehicles)
{
this.vehicles = vehicles;
//...
add(getScrollpane());
setSize(155,300);
}
public JScrollPane getScrollpane()
{
JPanel panel = new JPanel();
panel.setPreferredSize(new DimensionUIResource(150, 300));
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constraint = new GridBagConstraints();
panel.setLayout(gridbag);
constraint.fill = GridBagConstraints.HORIZONTAL;
JLabel title = new JLabel("Vehiles list");
constraint.gridwidth = 2;
constraint.gridx = 0;
constraint.gridy = 0;
constraint.ipady = 230;
gridbag.setConstraints(title, constraint);
panel.add(title);
// end of set title
constraint.gridwidth = 1;
int i=1;
for(JButton jb : v_buttons )
{
constraint.gridx =0;
constraint.gridy = i;
gridbag.setConstraints(jb, constraint);
panel.add(jb);
JLabel vehicle_lable = new JLabel("car" + i);
constraint.gridx = 1;
constraint.gridy = i;
gridbag.setConstraints(vehicle_lable, constraint);
panel.add(vehicle_lable);
i++;
}
JScrollPane jsp = new JScrollPane(panel);
return jsp;
}
}
in jaframe after add jscrollpane to jframe i place this
pack();
setSize(250, 250);
setLocation(100, 300);
and it work clearly!!!!
You also don't show us the layout manager of the VehicleList JPanel. In case you aren't setting it, it defaults to FlowLayout, unlike JFrame (which you mentioned this does work in), whose content pane defaults to BorderLayout. So maybe you just need to change the relevant code from:
//...
add(getScrollpane());
to
//...
setLayout(new BorderLayout());
add(getScrollpane(), BorderLayout.CENTER);
You need to set the scrolling policy on the horizontal and vertical:
public void setHorizontalScrollBarPolicy(int policy)
public void setVerticalScrollBarPolicy(int policy)
Using:
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
And:
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
JScrollPane.VERTICAL_SCROLLBAR_NEVER
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
So for example:
jscrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);